]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/Main.py
Works with wxX11 now.
[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
135 EVT_IDLE(self, self.OnIdle)
f6bcfd97 136 EVT_CLOSE(self, self.OnCloseWindow)
f3d9dc1d
RD
137 EVT_ICONIZE(self, self.OnIconfiy)
138 EVT_MAXIMIZE(self, self.OnMaximize)
cf694132
RD
139
140 self.Centre(wxBOTH)
141 self.CreateStatusBar(1, wxST_SIZEGRIP)
5a7823f5 142
f6bcfd97
BP
143 splitter = wxSplitterWindow(self, -1, style=wxNO_3D|wxSP_3D)
144 splitter2 = wxSplitterWindow(splitter, -1, style=wxNO_3D|wxSP_3D)
5a7823f5 145
d56cebe7
RD
146 def EmptyHandler(evt): pass
147 EVT_ERASE_BACKGROUND(splitter, EmptyHandler)
148 EVT_ERASE_BACKGROUND(splitter2, EmptyHandler)
cf694132 149
b1cfebd9 150 # Prevent TreeCtrl from displaying all items after destruction when true
cf694132
RD
151 self.dying = false
152
153 # Make a File menu
154 self.mainmenu = wxMenuBar()
155 menu = wxMenu()
2f90df85 156 exitID = wxNewId()
f0261a72 157 menu.Append(exitID, 'E&xit\tAlt-X', 'Get the heck outta here!')
2f90df85 158 EVT_MENU(self, exitID, self.OnFileExit)
cf694132
RD
159 self.mainmenu.Append(menu, '&File')
160
ec3e670f
RD
161 # Make a Demo menu
162 menu = wxMenu()
163 for item in _treeList:
164 submenu = wxMenu()
165 for childItem in item[1]:
166 mID = wxNewId()
167 submenu.Append(mID, childItem)
168 EVT_MENU(self, mID, self.OnDemoMenu)
169 menu.AppendMenu(wxNewId(), item[0], submenu)
170 self.mainmenu.Append(menu, '&Demo')
171
172
cf694132 173 # Make a Help menu
2f90df85 174 helpID = wxNewId()
cf694132 175 menu = wxMenu()
2f90df85
RD
176 menu.Append(helpID, '&About\tCtrl-H', 'wxPython RULES!!!')
177 EVT_MENU(self, helpID, self.OnHelpAbout)
cf694132
RD
178 self.mainmenu.Append(menu, '&Help')
179 self.SetMenuBar(self.mainmenu)
180
2f90df85 181 # set the menu accellerator table...
f0261a72 182 aTable = wxAcceleratorTable([(wxACCEL_ALT, ord('X'), exitID),
2f90df85
RD
183 (wxACCEL_CTRL, ord('H'), helpID)])
184 self.SetAcceleratorTable(aTable)
185
bb0054cd 186
cf694132 187 # Create a TreeCtrl
f6bcfd97
BP
188 tID = wxNewId()
189 self.treeMap = {}
190 self.tree = wxTreeCtrl(splitter, tID,
191 style=wxTR_HAS_BUTTONS |
192 wxTR_EDIT_LABELS |
afb810d9
RD
193 wxTR_HAS_VARIABLE_ROW_HEIGHT)
194
f6bcfd97 195 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
e9159fe8 196 root = self.tree.AddRoot("wxPython Overview")
f6bcfd97
BP
197 firstChild = None
198 for item in _treeList:
199 child = self.tree.AppendItem(root, item[0])
200 if not firstChild: firstChild = child
201 for childItem in item[1]:
202 theDemo = self.tree.AppendItem(child, childItem)
203 self.treeMap[childItem] = theDemo
204
205 self.tree.Expand(root)
206 self.tree.Expand(firstChild)
207 EVT_TREE_ITEM_EXPANDED (self.tree, tID, self.OnItemExpanded)
208 EVT_TREE_ITEM_COLLAPSED (self.tree, tID, self.OnItemCollapsed)
209 EVT_TREE_SEL_CHANGED (self.tree, tID, self.OnSelChanged)
210 EVT_LEFT_DOWN (self.tree, self.OnTreeLeftDown)
cf694132 211
cf694132 212 # Create a Notebook
d56cebe7 213 self.nb = wxNotebook(splitter2, -1, style=wxCLIP_CHILDREN)
cf694132 214
c368d904
RD
215 # Set up a wxHtmlWindow on the Overview Notebook page
216 # we put it in a panel first because there seems to be a
217 # refresh bug of some sort (wxGTK) when it is directly in
218 # the notebook...
219 if 0: # the old way
220 self.ovr = wxHtmlWindow(self.nb, -1, size=(400, 400))
e9159fe8 221 self.nb.AddPage(self.ovr, self.overviewText)
c368d904 222
e87269a7 223 else: # hopefully I can remove this hacky code soon, see bug #216861
d56cebe7 224 panel = wxPanel(self.nb, -1, style=wxCLIP_CHILDREN)
c368d904 225 self.ovr = wxHtmlWindow(panel, -1, size=(400, 400))
e9159fe8 226 self.nb.AddPage(panel, self.overviewText)
c368d904
RD
227
228 def OnOvrSize(evt, ovr=self.ovr):
229 ovr.SetSize(evt.GetSize())
230
231 EVT_SIZE(panel, OnOvrSize)
d56cebe7
RD
232 EVT_ERASE_BACKGROUND(panel, EmptyHandler)
233
c368d904 234
e9159fe8 235 self.SetOverview(self.overviewText, overview)
cf694132
RD
236
237
238 # Set up a TextCtrl on the Demo Code Notebook page
efc5f224
RD
239 self.txt = wxTextCtrl(self.nb, -1,
240 style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
cf694132
RD
241 self.nb.AddPage(self.txt, "Demo Code")
242
243
cf694132 244 # Set up a log on the View Log Notebook page
f6bcfd97 245 self.log = wxTextCtrl(splitter2, -1,
efc5f224 246 style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
f6bcfd97 247 # Set the wxWindows log target to be this textctrl
76bfdc78
RD
248 #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
249 wxLog_SetActiveTarget(MyLog(self.log))
cf694132
RD
250
251
5a7823f5 252
f6bcfd97 253 self.Show(true)
5a7823f5 254
f6bcfd97
BP
255 # add the windows to the splitter and split it.
256 splitter2.SplitHorizontally(self.nb, self.log)
f6bcfd97 257 splitter.SplitVertically(self.tree, splitter2)
afb810d9 258
f6bcfd97
BP
259 splitter.SetSashPosition(180, true)
260 splitter.SetMinimumPaneSize(20)
afb810d9
RD
261 splitter2.SetSashPosition(450, true)
262 splitter2.SetMinimumPaneSize(20)
263
cf694132 264
cf694132 265
bb0054cd
RD
266 # select initial items
267 self.nb.SetSelection(0)
f6bcfd97 268 self.tree.SelectItem(root)
ec3e670f
RD
269
270 if len(sys.argv) == 2:
271 try:
272 selectedDemo = self.treeMap[sys.argv[1]]
273 except:
274 selectedDemo = None
f6bcfd97 275 if selectedDemo:
ec3e670f
RD
276 self.tree.SelectItem(selectedDemo)
277 self.tree.EnsureVisible(selectedDemo)
278
bb0054cd 279
f6bcfd97 280 wxLogMessage('window handle: %s' % self.GetHandle())
2abc0a0f
RD
281
282
cf694132
RD
283 #---------------------------------------------
284 def WriteText(self, text):
f6bcfd97
BP
285 if text[-1:] == '\n':
286 text = text[:-1]
287 wxLogMessage(text)
288
cf694132
RD
289
290 def write(self, txt):
291 self.WriteText(txt)
292
293 #---------------------------------------------
294 def OnItemExpanded(self, event):
295 item = event.GetItem()
f6bcfd97 296 wxLogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
c368d904 297 event.Skip()
cf694132
RD
298
299 #---------------------------------------------
300 def OnItemCollapsed(self, event):
301 item = event.GetItem()
f6bcfd97 302 wxLogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
c368d904 303 event.Skip()
f6bcfd97
BP
304
305 #---------------------------------------------
306 def OnTreeLeftDown(self, event):
307 pt = event.GetPosition();
308 item, flags = self.tree.HitTest(pt)
309 if item == self.tree.GetSelection():
310 self.SetOverview(self.tree.GetItemText(item), self.curOverview)
185d7c3e 311 event.Skip()
cf694132
RD
312
313 #---------------------------------------------
314 def OnSelChanged(self, event):
315 if self.dying:
316 return
317
5a7823f5
RD
318 item = event.GetItem()
319 itemText = self.tree.GetItemText(item)
320 self.RunDemo(itemText)
321
322
323 #---------------------------------------------
324 def RunDemo(self, itemText):
694759cf 325 os.chdir(self.cwd)
cf694132
RD
326 if self.nb.GetPageCount() == 3:
327 if self.nb.GetSelection() == 2:
328 self.nb.SetSelection(0)
329 self.nb.DeletePage(2)
330
e9159fe8 331 if itemText == self.overviewText:
cf694132 332 self.GetDemoFile('Main.py')
e9159fe8 333 self.SetOverview(self.overviewText, overview)
cf694132 334 self.nb.Refresh();
e91a9dfc 335 self.window = None
cf694132
RD
336
337 else:
338 if os.path.exists(itemText + '.py'):
9d8bd15f 339 wxBeginBusyCursor()
f6bcfd97
BP
340 wxLogMessage("Running demo %s.py..." % itemText)
341 try:
342 self.GetDemoFile(itemText + '.py')
343 module = __import__(itemText, globals())
e9159fe8 344 self.SetOverview(itemText + " Overview", module.overview)
f6bcfd97
BP
345 finally:
346 wxEndBusyCursor()
cf694132
RD
347
348 # in case runTest is modal, make sure things look right...
349 self.nb.Refresh();
350 wxYield()
351
f6bcfd97 352 self.window = module.runTest(self, self.nb, self) ###
e91a9dfc
RD
353 if self.window:
354 self.nb.AddPage(self.window, 'Demo')
dcd38683 355 wxYield()
cf694132 356 self.nb.SetSelection(2)
cf694132
RD
357
358 else:
f6bcfd97 359 self.ovr.SetPage("")
cf694132 360 self.txt.Clear()
e91a9dfc 361 self.window = None
cf694132 362
2f90df85 363
cf694132
RD
364
365 #---------------------------------------------
366 # Get the Demo files
367 def GetDemoFile(self, filename):
368 self.txt.Clear()
bb0054cd
RD
369 try:
370 self.txt.SetValue(open(filename).read())
8bf5d46e 371 except IOError:
cf694132
RD
372 self.txt.WriteText("Cannot open %s file." % filename)
373
374 self.txt.SetInsertionPoint(0)
375 self.txt.ShowPosition(0)
376
377 #---------------------------------------------
378 def SetOverview(self, name, text):
f6bcfd97
BP
379 self.curOverview = text
380 lead = text[:6]
381 if lead != '<html>' and lead != '<HTML>':
382 text = string.join(string.split(text, '\n'), '<br>')
f6bcfd97 383 self.ovr.SetPage(text)
cf694132 384 self.nb.SetPageText(0, name)
cf694132
RD
385
386 #---------------------------------------------
387 # Menu methods
c368d904 388 def OnFileExit(self, *event):
cf694132
RD
389 self.Close()
390
391
392 def OnHelpAbout(self, event):
e166644c 393 from About import MyAboutBox
ec3e670f 394 about = MyAboutBox(self)
cf694132
RD
395 about.ShowModal()
396 about.Destroy()
397
398
399 #---------------------------------------------
400 def OnCloseWindow(self, event):
401 self.dying = true
e91a9dfc 402 self.window = None
26197023 403 self.mainmenu = None
c368d904
RD
404 if hasattr(self, "tbicon"):
405 del self.tbicon
cf694132
RD
406 self.Destroy()
407
c368d904 408
cf694132
RD
409 #---------------------------------------------
410 def OnIdle(self, event):
411 if self.otherWin:
412 self.otherWin.Raise()
e91a9dfc 413 self.window = self.otherWin
cf694132
RD
414 self.otherWin = None
415
ec3e670f
RD
416 #---------------------------------------------
417 def OnDemoMenu(self, event):
f6bcfd97
BP
418 try:
419 selectedDemo = self.treeMap[self.mainmenu.GetLabel(event.GetId())]
420 except:
421 selectedDemo = None
422 if selectedDemo:
423 self.tree.SelectItem(selectedDemo)
424 self.tree.EnsureVisible(selectedDemo)
ec3e670f 425
c368d904
RD
426
427 #---------------------------------------------
428 def OnTaskBarActivate(self, evt):
429 if self.IsIconized():
430 self.Iconize(false)
431 if not self.IsShown():
432 self.Show(true)
433 self.Raise()
434
435 #---------------------------------------------
436
437 TBMENU_RESTORE = 1000
438 TBMENU_CLOSE = 1001
439
440 def OnTaskBarMenu(self, evt):
441 menu = wxMenu()
442 menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
443 menu.Append(self.TBMENU_CLOSE, "Close")
444 self.tbicon.PopupMenu(menu)
445 menu.Destroy()
446
447 #---------------------------------------------
448 def OnTaskBarClose(self, evt):
449 self.Close()
450
451 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
452 # prod the main idle handler a bit to get the window to actually close
453 wxGetApp().ProcessIdle()
454
455
f3d9dc1d
RD
456 #---------------------------------------------
457 def OnIconfiy(self, evt):
458 wxLogMessage("OnIconfiy")
459 evt.Skip()
460
461 #---------------------------------------------
462 def OnMaximize(self, evt):
463 wxLogMessage("OnMaximize")
464 evt.Skip()
465
466
467
468
cf694132
RD
469#---------------------------------------------------------------------------
470#---------------------------------------------------------------------------
471
b5a5d647
RD
472class MySplashScreen(wxSplashScreen):
473 def __init__(self):
6c5ae2d2 474 bmp = wxImage(opj("bitmaps/splash.gif")).ConvertToBitmap()
b5a5d647
RD
475 wxSplashScreen.__init__(self, bmp,
476 wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT,
477 4000, None, -1)
478 EVT_CLOSE(self, self.OnClose)
479
480 def OnClose(self, evt):
9fb56e0c 481 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
cf694132 482 frame.Show(true)
f6bcfd97 483 self.ShowTip(frame)
a1bfae9d 484 self.Destroy()
f6bcfd97
BP
485
486 def ShowTip(self, frame):
487 try:
6c5ae2d2 488 showTipText = open(opj("data/showTips")).read()
f6bcfd97
BP
489 showTip, index = eval(showTipText)
490 except IOError:
491 showTip, index = (1, 0)
f6bcfd97 492 if showTip:
6c5ae2d2 493 tp = wxCreateFileTipProvider(opj("data/tips.txt"), index)
f6bcfd97
BP
494 showTip = wxShowTip(frame, tp)
495 index = tp.GetCurrentTip()
6c5ae2d2 496 open(opj("data/showTips"), "w").write(str( (showTip, index) ))
f6bcfd97 497
cf694132 498
b5a5d647
RD
499
500class MyApp(wxApp):
501 def OnInit(self):
502 """
68320e40 503 Create and show the splash screen. It will then create and show
b5a5d647
RD
504 the main frame when it is time to do so.
505 """
506 wxInitAllImageHandlers()
507 splash = MySplashScreen()
508 splash.Show()
509 wxYield()
510 return true
511
512
513
cf694132
RD
514#---------------------------------------------------------------------------
515
516def main():
e02c03a4 517 try:
d56cebe7 518 demoPath = os.path.dirname(__file__)
e02c03a4
RD
519 os.chdir(demoPath)
520 except:
521 pass
cf694132
RD
522 app = MyApp(0)
523 app.MainLoop()
524
525
526#---------------------------------------------------------------------------
527
528
529
f6bcfd97
BP
530overview = """<html><body>
531 <h2>Python</h2>
532
533 Python is an interpreted, interactive, object-oriented programming
534 language often compared to Tcl, Perl, Scheme, or Java.
535
536 <p> Python combines remarkable power with very clear syntax. It has
537 modules, classes, exceptions, very high level dynamic data types, and
538 dynamic typing. There are interfaces to many system calls and
539 libraries, and new built-in modules are easily written in C or
540 C++. Python is also usable as an extension language for applications
541 that need a programmable interface. <p>
542
543 <h2>wxWindows</h2>
544
545 wxWindows is a free C++ framework designed to make cross-platform
546 programming child's play. Well, almost. wxWindows 2 supports Windows
547 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
548 underway. Other ports are under consideration. <p>
549
550 wxWindows is a set of libraries that allows C++ applications to
551 compile and run on several different types of computers, with minimal
552 source code changes. There is one library per supported GUI (such as
553 Motif, or Windows). As well as providing a common API (Application
554 Programming Interface) for GUI functionality, it provides
555 functionality for accessing some commonly-used operating system
556 facilities, such as copying or deleting files. wxWindows is a
557 'framework' in the sense that it provides a lot of built-in
558 functionality, which the application can use or replace as required,
559 thus saving a great deal of coding effort. Basic data structures such
560 as strings, linked lists and hash tables are also supported.
561
562 <p>
563 <h2>wxPython</h2>
564
565 wxPython is a Python extension module that encapsulates the wxWindows
566 GUI classes. Currently it is only available for the Win32 and GTK
567 ports of wxWindows, but as soon as the other ports are brought up to
568 the same level as Win32 and GTK, it should be fairly trivial to
569 enable wxPython to be used with the new GUI.
570
571 <p>
572
573 The wxPython extension module attempts to mirror the class heiarchy
574 of wxWindows as closely as possible. This means that there is a
575 wxFrame class in wxPython that looks, smells, tastes and acts almost
576 the same as the wxFrame class in the C++ version. Unfortunately,
577 because of differences in the languages, wxPython doesn't match
578 wxWindows exactly, but the differences should be easy to absorb
579 because they are natural to Python. For example, some methods that
580 return multiple values via argument pointers in C++ will return a
581 tuple of values in Python.
582
583 <p>
584
585 There is still much to be done for wxPython, many classes still need
586 to be mirrored. Also, wxWindows is still somewhat of a moving target
587 so it is a bit of an effort just keeping wxPython up to date. On the
588 other hand, there are enough of the core classes completed that
589 useful applications can be written.
590
591 <p>
592
593 wxPython is close enough to the C++ version that the majority of
594 the wxPython documentation is actually just notes attached to the C++
595 documents that describe the places where wxPython is different. There
596 is also a series of sample programs included, and a series of
597 documentation pages that assist the programmer in getting started
598 with wxPython.
599
600 """
cf694132
RD
601
602
603#----------------------------------------------------------------------------
604#----------------------------------------------------------------------------
605
606if __name__ == '__main__':
607 main()
608
609#----------------------------------------------------------------------------
610
611
612
613
614
615
616