]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/Main.py
Added wxListCtrlAutoWidthMixin from Erik Westra.
[wxWidgets.git] / wxPython / demo / Main.py
CommitLineData
cf694132
RD
1#!/bin/env python
2#----------------------------------------------------------------------------
3# Name: Main.py
4# Purpose: Testing lots of stuff, controls, window types, etc.
5#
f6bcfd97 6# Author: Robin Dunn
cf694132 7#
f6bcfd97 8# Created: A long time ago, in a galaxy far, far away...
cf694132
RD
9# RCS-ID: $Id$
10# Copyright: (c) 1999 by Total Control Software
11# Licence: wxWindows license
12#----------------------------------------------------------------------------
13
6c5ae2d2 14import sys, os, time, string
cf694132 15from wxPython.wx import *
f6bcfd97 16from wxPython.html import wxHtmlWindow
cf694132 17
96bfd053
RD
18import images
19
cf694132
RD
20#---------------------------------------------------------------------------
21
22
23_treeList = [
68320e40 24 ('New since last release', ['wxGenericDirCtrl',
f74ff5ef 25 'wxImageFromStream',
96de41c2 26 'RowColSizer',
03d84e7a 27 'Unicode',
f6bcfd97 28 ]),
e395c057 29
6d19860f 30 ('Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame',
6d19860f
RD
31 'wxGrid', 'wxSashWindow',
32 'wxScrolledWindow', 'wxSplitterWindow',
33 'wxStatusBar', 'wxNotebook',
34 'wxHtmlWindow',
0122b7e3 35 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',
a57d56d6 36 'wxPopupWindow',
ebf4302c 37 'wxDynamicSashWindow',
0122b7e3 38 ]),
cf694132
RD
39
40 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
41 'wxSingleChoiceDialog', 'wxTextEntryDialog',
42 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
0122b7e3
RD
43 'wxMessageDialog', 'wxProgressDialog', 'wxFindReplaceDialog',
44 ]),
cf694132
RD
45
46 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
68320e40
RD
47 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'VirtualListCtrl',
48 'wxTextCtrl',
f6bcfd97
BP
49 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
50 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
d1679124 51 'wxCalendarCtrl', 'wxToggleButton',
950e7faf 52 'wxEditableListBox', 'wxLEDNumberCtrl',
6999b0d8 53 ]),
cf694132 54
96de41c2
RD
55 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource',
56 'RowColSizer',
57 ]),
cf694132 58
846ec2f9
RD
59 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'URLDragAndDrop',
60 'FontEnumerator',
b1462dfa 61 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
9b3d3bc4 62 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
f6bcfd97
BP
63 'PythonEvents', 'Threads',
64 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
493f1553 65 'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
b37c7e1d 66 'wxJoystick', 'DrawXXXList', 'ErrorDialogs', 'wxMimeTypesManager',
03d84e7a 67 'ContextHelp', 'SplitTree', 'Unicode',
f6bcfd97 68 ]),
cf694132 69
e0473f5f 70 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
f0261a72 71 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
c7e7022c 72 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
c368d904 73 'FileBrowseButton', 'GenericButtons', 'wxEditor',
c7e7022c 74 'ColourSelect', 'ImageBrowser',
68320e40
RD
75 'infoframe', 'ColourDB', 'PyCrust', 'PyCrustWithFilling',
76 'TablePrint',
729f4276 77 'wxRightTextCtrl',
c368d904 78 ]),
cf694132 79
611dc22c
RD
80 ('Cool Contribs', ['pyTree', 'hangman',
81 #'SlashDot',
82 'XMLtreeview'
83 ]),
cf694132
RD
84
85 ]
86
87#---------------------------------------------------------------------------
88
76bfdc78
RD
89class MyLog(wxPyLog):
90 def __init__(self, textCtrl, logTime=0):
91 wxPyLog.__init__(self)
92 self.tc = textCtrl
93 self.logTime = logTime
94
95 def DoLogString(self, message, timeStamp):
96 if self.logTime:
97 message = time.strftime("%X", time.localtime(timeStamp)) + \
98 ": " + message
99 self.tc.AppendText(message + '\n')
100
101
6c5ae2d2
RD
102#---------------------------------------------------------------------------
103
104def opj(path):
105 """Convert paths to the platform-specific separator"""
106 return apply(os.path.join, tuple(string.split(path, '/')))
107
108
76bfdc78
RD
109#---------------------------------------------------------------------------
110
cf694132 111class wxPythonDemo(wxFrame):
e9159fe8 112 overviewText = "wxPython Overview"
c368d904 113
cf694132 114 def __init__(self, parent, id, title):
f6bcfd97
BP
115 wxFrame.__init__(self, parent, -1, title, size = (800, 600),
116 style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE)
2f90df85 117
694759cf 118 self.cwd = os.getcwd()
3ca6a5f0 119 self.curOverview = ""
694759cf 120
afb810d9 121 icon = images.getMondrianIcon()
96bfd053 122 self.SetIcon(icon)
c368d904 123
96bfd053 124 if wxPlatform == '__WXMSW__':
c368d904
RD
125 # setup a taskbar icon, and catch some events from it
126 self.tbicon = wxTaskBarIcon()
127 self.tbicon.SetIcon(icon, "wxPython Demo")
128 EVT_TASKBAR_LEFT_DCLICK(self.tbicon, self.OnTaskBarActivate)
129 EVT_TASKBAR_RIGHT_UP(self.tbicon, self.OnTaskBarMenu)
130 EVT_MENU(self.tbicon, self.TBMENU_RESTORE, self.OnTaskBarActivate)
131 EVT_MENU(self.tbicon, self.TBMENU_CLOSE, self.OnTaskBarClose)
132
cf694132
RD
133
134 self.otherWin = None
ccf691a4 135 self.showTip = true
cf694132 136 EVT_IDLE(self, self.OnIdle)
f6bcfd97 137 EVT_CLOSE(self, self.OnCloseWindow)
f3d9dc1d
RD
138 EVT_ICONIZE(self, self.OnIconfiy)
139 EVT_MAXIMIZE(self, self.OnMaximize)
cf694132
RD
140
141 self.Centre(wxBOTH)
142 self.CreateStatusBar(1, wxST_SIZEGRIP)
5a7823f5 143
f6bcfd97
BP
144 splitter = wxSplitterWindow(self, -1, style=wxNO_3D|wxSP_3D)
145 splitter2 = wxSplitterWindow(splitter, -1, style=wxNO_3D|wxSP_3D)
5a7823f5 146
d56cebe7
RD
147 def EmptyHandler(evt): pass
148 EVT_ERASE_BACKGROUND(splitter, EmptyHandler)
149 EVT_ERASE_BACKGROUND(splitter2, EmptyHandler)
cf694132 150
b1cfebd9 151 # Prevent TreeCtrl from displaying all items after destruction when true
cf694132
RD
152 self.dying = false
153
154 # Make a File menu
155 self.mainmenu = wxMenuBar()
156 menu = wxMenu()
2f90df85 157 exitID = wxNewId()
f0261a72 158 menu.Append(exitID, 'E&xit\tAlt-X', 'Get the heck outta here!')
2f90df85 159 EVT_MENU(self, exitID, self.OnFileExit)
cf694132
RD
160 self.mainmenu.Append(menu, '&File')
161
ec3e670f
RD
162 # Make a Demo menu
163 menu = wxMenu()
164 for item in _treeList:
165 submenu = wxMenu()
166 for childItem in item[1]:
167 mID = wxNewId()
168 submenu.Append(mID, childItem)
169 EVT_MENU(self, mID, self.OnDemoMenu)
170 menu.AppendMenu(wxNewId(), item[0], submenu)
171 self.mainmenu.Append(menu, '&Demo')
172
173
cf694132 174 # Make a Help menu
2f90df85 175 helpID = wxNewId()
cf694132 176 menu = wxMenu()
2f90df85
RD
177 menu.Append(helpID, '&About\tCtrl-H', 'wxPython RULES!!!')
178 EVT_MENU(self, helpID, self.OnHelpAbout)
cf694132
RD
179 self.mainmenu.Append(menu, '&Help')
180 self.SetMenuBar(self.mainmenu)
181
2f90df85 182 # set the menu accellerator table...
f0261a72 183 aTable = wxAcceleratorTable([(wxACCEL_ALT, ord('X'), exitID),
2f90df85
RD
184 (wxACCEL_CTRL, ord('H'), helpID)])
185 self.SetAcceleratorTable(aTable)
186
bb0054cd 187
cf694132 188 # Create a TreeCtrl
f6bcfd97
BP
189 tID = wxNewId()
190 self.treeMap = {}
191 self.tree = wxTreeCtrl(splitter, tID,
192 style=wxTR_HAS_BUTTONS |
193 wxTR_EDIT_LABELS |
afb810d9
RD
194 wxTR_HAS_VARIABLE_ROW_HEIGHT)
195
f6bcfd97 196 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
e9159fe8 197 root = self.tree.AddRoot("wxPython Overview")
f6bcfd97
BP
198 firstChild = None
199 for item in _treeList:
200 child = self.tree.AppendItem(root, item[0])
201 if not firstChild: firstChild = child
202 for childItem in item[1]:
203 theDemo = self.tree.AppendItem(child, childItem)
204 self.treeMap[childItem] = theDemo
205
206 self.tree.Expand(root)
207 self.tree.Expand(firstChild)
208 EVT_TREE_ITEM_EXPANDED (self.tree, tID, self.OnItemExpanded)
209 EVT_TREE_ITEM_COLLAPSED (self.tree, tID, self.OnItemCollapsed)
210 EVT_TREE_SEL_CHANGED (self.tree, tID, self.OnSelChanged)
211 EVT_LEFT_DOWN (self.tree, self.OnTreeLeftDown)
cf694132 212
cf694132 213 # Create a Notebook
d56cebe7 214 self.nb = wxNotebook(splitter2, -1, style=wxCLIP_CHILDREN)
cf694132 215
c368d904
RD
216 # Set up a wxHtmlWindow on the Overview Notebook page
217 # we put it in a panel first because there seems to be a
218 # refresh bug of some sort (wxGTK) when it is directly in
219 # the notebook...
220 if 0: # the old way
221 self.ovr = wxHtmlWindow(self.nb, -1, size=(400, 400))
e9159fe8 222 self.nb.AddPage(self.ovr, self.overviewText)
c368d904 223
e87269a7 224 else: # hopefully I can remove this hacky code soon, see bug #216861
d56cebe7 225 panel = wxPanel(self.nb, -1, style=wxCLIP_CHILDREN)
c368d904 226 self.ovr = wxHtmlWindow(panel, -1, size=(400, 400))
e9159fe8 227 self.nb.AddPage(panel, self.overviewText)
c368d904
RD
228
229 def OnOvrSize(evt, ovr=self.ovr):
230 ovr.SetSize(evt.GetSize())
231
232 EVT_SIZE(panel, OnOvrSize)
d56cebe7
RD
233 EVT_ERASE_BACKGROUND(panel, EmptyHandler)
234
c368d904 235
e9159fe8 236 self.SetOverview(self.overviewText, overview)
cf694132
RD
237
238
239 # Set up a TextCtrl on the Demo Code Notebook page
efc5f224
RD
240 self.txt = wxTextCtrl(self.nb, -1,
241 style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
cf694132
RD
242 self.nb.AddPage(self.txt, "Demo Code")
243
244
cf694132 245 # Set up a log on the View Log Notebook page
f6bcfd97 246 self.log = wxTextCtrl(splitter2, -1,
efc5f224 247 style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
342639eb 248
f6bcfd97 249 # Set the wxWindows log target to be this textctrl
76bfdc78 250 #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
342639eb
RD
251
252 # But instead of the above we want to show how to use our own wxLog class
76bfdc78 253 wxLog_SetActiveTarget(MyLog(self.log))
cf694132
RD
254
255
5a7823f5 256
f6bcfd97 257 self.Show(true)
5a7823f5 258
f6bcfd97
BP
259 # add the windows to the splitter and split it.
260 splitter2.SplitHorizontally(self.nb, self.log)
f6bcfd97 261 splitter.SplitVertically(self.tree, splitter2)
afb810d9 262
f6bcfd97
BP
263 splitter.SetSashPosition(180, true)
264 splitter.SetMinimumPaneSize(20)
afb810d9
RD
265 splitter2.SetSashPosition(450, true)
266 splitter2.SetMinimumPaneSize(20)
267
cf694132 268
cf694132 269
bb0054cd
RD
270 # select initial items
271 self.nb.SetSelection(0)
f6bcfd97 272 self.tree.SelectItem(root)
ec3e670f
RD
273
274 if len(sys.argv) == 2:
275 try:
276 selectedDemo = self.treeMap[sys.argv[1]]
277 except:
278 selectedDemo = None
f6bcfd97 279 if selectedDemo:
ec3e670f
RD
280 self.tree.SelectItem(selectedDemo)
281 self.tree.EnsureVisible(selectedDemo)
282
bb0054cd 283
f6bcfd97 284 wxLogMessage('window handle: %s' % self.GetHandle())
2abc0a0f
RD
285
286
cf694132
RD
287 #---------------------------------------------
288 def WriteText(self, text):
f6bcfd97
BP
289 if text[-1:] == '\n':
290 text = text[:-1]
291 wxLogMessage(text)
292
cf694132
RD
293
294 def write(self, txt):
295 self.WriteText(txt)
296
297 #---------------------------------------------
298 def OnItemExpanded(self, event):
299 item = event.GetItem()
f6bcfd97 300 wxLogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
c368d904 301 event.Skip()
cf694132
RD
302
303 #---------------------------------------------
304 def OnItemCollapsed(self, event):
305 item = event.GetItem()
f6bcfd97 306 wxLogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
c368d904 307 event.Skip()
f6bcfd97
BP
308
309 #---------------------------------------------
310 def OnTreeLeftDown(self, event):
311 pt = event.GetPosition();
312 item, flags = self.tree.HitTest(pt)
313 if item == self.tree.GetSelection():
314 self.SetOverview(self.tree.GetItemText(item), self.curOverview)
185d7c3e 315 event.Skip()
cf694132
RD
316
317 #---------------------------------------------
318 def OnSelChanged(self, event):
319 if self.dying:
320 return
321
5a7823f5
RD
322 item = event.GetItem()
323 itemText = self.tree.GetItemText(item)
324 self.RunDemo(itemText)
325
326
327 #---------------------------------------------
328 def RunDemo(self, itemText):
694759cf 329 os.chdir(self.cwd)
cf694132
RD
330 if self.nb.GetPageCount() == 3:
331 if self.nb.GetSelection() == 2:
332 self.nb.SetSelection(0)
333 self.nb.DeletePage(2)
334
e9159fe8 335 if itemText == self.overviewText:
cf694132 336 self.GetDemoFile('Main.py')
e9159fe8 337 self.SetOverview(self.overviewText, overview)
cf694132 338 self.nb.Refresh();
e91a9dfc 339 self.window = None
cf694132
RD
340
341 else:
342 if os.path.exists(itemText + '.py'):
9d8bd15f 343 wxBeginBusyCursor()
f6bcfd97
BP
344 wxLogMessage("Running demo %s.py..." % itemText)
345 try:
346 self.GetDemoFile(itemText + '.py')
347 module = __import__(itemText, globals())
e9159fe8 348 self.SetOverview(itemText + " Overview", module.overview)
f6bcfd97
BP
349 finally:
350 wxEndBusyCursor()
cf694132
RD
351
352 # in case runTest is modal, make sure things look right...
353 self.nb.Refresh();
354 wxYield()
355
f6bcfd97 356 self.window = module.runTest(self, self.nb, self) ###
e91a9dfc
RD
357 if self.window:
358 self.nb.AddPage(self.window, 'Demo')
dcd38683 359 wxYield()
cf694132 360 self.nb.SetSelection(2)
cf694132
RD
361
362 else:
f6bcfd97 363 self.ovr.SetPage("")
cf694132 364 self.txt.Clear()
e91a9dfc 365 self.window = None
cf694132 366
2f90df85 367
cf694132
RD
368
369 #---------------------------------------------
370 # Get the Demo files
371 def GetDemoFile(self, filename):
372 self.txt.Clear()
bb0054cd
RD
373 try:
374 self.txt.SetValue(open(filename).read())
8bf5d46e 375 except IOError:
cf694132
RD
376 self.txt.WriteText("Cannot open %s file." % filename)
377
378 self.txt.SetInsertionPoint(0)
379 self.txt.ShowPosition(0)
380
381 #---------------------------------------------
382 def SetOverview(self, name, text):
f6bcfd97
BP
383 self.curOverview = text
384 lead = text[:6]
385 if lead != '<html>' and lead != '<HTML>':
386 text = string.join(string.split(text, '\n'), '<br>')
f6bcfd97 387 self.ovr.SetPage(text)
cf694132 388 self.nb.SetPageText(0, name)
cf694132
RD
389
390 #---------------------------------------------
391 # Menu methods
c368d904 392 def OnFileExit(self, *event):
cf694132
RD
393 self.Close()
394
395
396 def OnHelpAbout(self, event):
e166644c 397 from About import MyAboutBox
ec3e670f 398 about = MyAboutBox(self)
cf694132
RD
399 about.ShowModal()
400 about.Destroy()
401
402
403 #---------------------------------------------
404 def OnCloseWindow(self, event):
405 self.dying = true
e91a9dfc 406 self.window = None
26197023 407 self.mainmenu = None
c368d904
RD
408 if hasattr(self, "tbicon"):
409 del self.tbicon
cf694132
RD
410 self.Destroy()
411
c368d904 412
cf694132
RD
413 #---------------------------------------------
414 def OnIdle(self, event):
415 if self.otherWin:
416 self.otherWin.Raise()
e91a9dfc 417 self.window = self.otherWin
cf694132
RD
418 self.otherWin = None
419
ccf691a4
RD
420 if self.showTip:
421 self.ShowTip()
422 self.showTip = false
423
424
425 #---------------------------------------------
426 def ShowTip(self):
427 try:
428 showTipText = open(opj("data/showTips")).read()
429 showTip, index = eval(showTipText)
430 except IOError:
431 showTip, index = (1, 0)
432 if showTip:
433 tp = wxCreateFileTipProvider(opj("data/tips.txt"), index)
434 showTip = wxShowTip(self, tp)
435 index = tp.GetCurrentTip()
436 open(opj("data/showTips"), "w").write(str( (showTip, index) ))
437
438
ec3e670f
RD
439 #---------------------------------------------
440 def OnDemoMenu(self, event):
f6bcfd97
BP
441 try:
442 selectedDemo = self.treeMap[self.mainmenu.GetLabel(event.GetId())]
443 except:
444 selectedDemo = None
445 if selectedDemo:
446 self.tree.SelectItem(selectedDemo)
447 self.tree.EnsureVisible(selectedDemo)
ec3e670f 448
c368d904
RD
449
450 #---------------------------------------------
451 def OnTaskBarActivate(self, evt):
452 if self.IsIconized():
453 self.Iconize(false)
454 if not self.IsShown():
455 self.Show(true)
456 self.Raise()
457
458 #---------------------------------------------
459
460 TBMENU_RESTORE = 1000
461 TBMENU_CLOSE = 1001
462
463 def OnTaskBarMenu(self, evt):
464 menu = wxMenu()
465 menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
466 menu.Append(self.TBMENU_CLOSE, "Close")
467 self.tbicon.PopupMenu(menu)
468 menu.Destroy()
469
470 #---------------------------------------------
471 def OnTaskBarClose(self, evt):
472 self.Close()
473
474 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
475 # prod the main idle handler a bit to get the window to actually close
476 wxGetApp().ProcessIdle()
477
478
f3d9dc1d
RD
479 #---------------------------------------------
480 def OnIconfiy(self, evt):
481 wxLogMessage("OnIconfiy")
482 evt.Skip()
483
484 #---------------------------------------------
485 def OnMaximize(self, evt):
486 wxLogMessage("OnMaximize")
487 evt.Skip()
488
489
490
491
cf694132
RD
492#---------------------------------------------------------------------------
493#---------------------------------------------------------------------------
494
b5a5d647
RD
495class MySplashScreen(wxSplashScreen):
496 def __init__(self):
6c5ae2d2 497 bmp = wxImage(opj("bitmaps/splash.gif")).ConvertToBitmap()
b5a5d647
RD
498 wxSplashScreen.__init__(self, bmp,
499 wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT,
500 4000, None, -1)
501 EVT_CLOSE(self, self.OnClose)
502
503 def OnClose(self, evt):
9fb56e0c 504 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
cf694132 505 frame.Show(true)
ccf691a4 506 evt.Skip() # Make sure the default handler runs too...
cf694132 507
b5a5d647
RD
508
509class MyApp(wxApp):
510 def OnInit(self):
511 """
68320e40 512 Create and show the splash screen. It will then create and show
b5a5d647
RD
513 the main frame when it is time to do so.
514 """
515 wxInitAllImageHandlers()
516 splash = MySplashScreen()
517 splash.Show()
b5a5d647
RD
518 return true
519
520
521
cf694132
RD
522#---------------------------------------------------------------------------
523
524def main():
e02c03a4 525 try:
d56cebe7 526 demoPath = os.path.dirname(__file__)
e02c03a4
RD
527 os.chdir(demoPath)
528 except:
529 pass
cf694132
RD
530 app = MyApp(0)
531 app.MainLoop()
532
533
534#---------------------------------------------------------------------------
535
536
537
f6bcfd97
BP
538overview = """<html><body>
539 <h2>Python</h2>
540
541 Python is an interpreted, interactive, object-oriented programming
542 language often compared to Tcl, Perl, Scheme, or Java.
543
544 <p> Python combines remarkable power with very clear syntax. It has
545 modules, classes, exceptions, very high level dynamic data types, and
546 dynamic typing. There are interfaces to many system calls and
547 libraries, and new built-in modules are easily written in C or
548 C++. Python is also usable as an extension language for applications
549 that need a programmable interface. <p>
550
551 <h2>wxWindows</h2>
552
553 wxWindows is a free C++ framework designed to make cross-platform
554 programming child's play. Well, almost. wxWindows 2 supports Windows
555 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
556 underway. Other ports are under consideration. <p>
557
558 wxWindows is a set of libraries that allows C++ applications to
559 compile and run on several different types of computers, with minimal
560 source code changes. There is one library per supported GUI (such as
561 Motif, or Windows). As well as providing a common API (Application
562 Programming Interface) for GUI functionality, it provides
563 functionality for accessing some commonly-used operating system
564 facilities, such as copying or deleting files. wxWindows is a
565 'framework' in the sense that it provides a lot of built-in
566 functionality, which the application can use or replace as required,
567 thus saving a great deal of coding effort. Basic data structures such
568 as strings, linked lists and hash tables are also supported.
569
570 <p>
571 <h2>wxPython</h2>
572
573 wxPython is a Python extension module that encapsulates the wxWindows
574 GUI classes. Currently it is only available for the Win32 and GTK
575 ports of wxWindows, but as soon as the other ports are brought up to
576 the same level as Win32 and GTK, it should be fairly trivial to
577 enable wxPython to be used with the new GUI.
578
579 <p>
580
581 The wxPython extension module attempts to mirror the class heiarchy
582 of wxWindows as closely as possible. This means that there is a
583 wxFrame class in wxPython that looks, smells, tastes and acts almost
584 the same as the wxFrame class in the C++ version. Unfortunately,
585 because of differences in the languages, wxPython doesn't match
586 wxWindows exactly, but the differences should be easy to absorb
587 because they are natural to Python. For example, some methods that
588 return multiple values via argument pointers in C++ will return a
589 tuple of values in Python.
590
591 <p>
592
593 There is still much to be done for wxPython, many classes still need
594 to be mirrored. Also, wxWindows is still somewhat of a moving target
595 so it is a bit of an effort just keeping wxPython up to date. On the
596 other hand, there are enough of the core classes completed that
597 useful applications can be written.
598
599 <p>
600
601 wxPython is close enough to the C++ version that the majority of
602 the wxPython documentation is actually just notes attached to the C++
603 documents that describe the places where wxPython is different. There
604 is also a series of sample programs included, and a series of
605 documentation pages that assist the programmer in getting started
606 with wxPython.
607
608 """
cf694132
RD
609
610
611#----------------------------------------------------------------------------
612#----------------------------------------------------------------------------
613
614if __name__ == '__main__':
615 main()
616
617#----------------------------------------------------------------------------
618
619
620
621
622
623
624