]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/Main.py
wxhtml.rc no longer needed
[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)
f6bcfd97 248 # Set the wxWindows log target to be this textctrl
76bfdc78
RD
249 #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
250 wxLog_SetActiveTarget(MyLog(self.log))
cf694132
RD
251
252
5a7823f5 253
f6bcfd97 254 self.Show(true)
5a7823f5 255
f6bcfd97
BP
256 # add the windows to the splitter and split it.
257 splitter2.SplitHorizontally(self.nb, self.log)
f6bcfd97 258 splitter.SplitVertically(self.tree, splitter2)
afb810d9 259
f6bcfd97
BP
260 splitter.SetSashPosition(180, true)
261 splitter.SetMinimumPaneSize(20)
afb810d9
RD
262 splitter2.SetSashPosition(450, true)
263 splitter2.SetMinimumPaneSize(20)
264
cf694132 265
cf694132 266
bb0054cd
RD
267 # select initial items
268 self.nb.SetSelection(0)
f6bcfd97 269 self.tree.SelectItem(root)
ec3e670f
RD
270
271 if len(sys.argv) == 2:
272 try:
273 selectedDemo = self.treeMap[sys.argv[1]]
274 except:
275 selectedDemo = None
f6bcfd97 276 if selectedDemo:
ec3e670f
RD
277 self.tree.SelectItem(selectedDemo)
278 self.tree.EnsureVisible(selectedDemo)
279
bb0054cd 280
f6bcfd97 281 wxLogMessage('window handle: %s' % self.GetHandle())
2abc0a0f
RD
282
283
cf694132
RD
284 #---------------------------------------------
285 def WriteText(self, text):
f6bcfd97
BP
286 if text[-1:] == '\n':
287 text = text[:-1]
288 wxLogMessage(text)
289
cf694132
RD
290
291 def write(self, txt):
292 self.WriteText(txt)
293
294 #---------------------------------------------
295 def OnItemExpanded(self, event):
296 item = event.GetItem()
f6bcfd97 297 wxLogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
c368d904 298 event.Skip()
cf694132
RD
299
300 #---------------------------------------------
301 def OnItemCollapsed(self, event):
302 item = event.GetItem()
f6bcfd97 303 wxLogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
c368d904 304 event.Skip()
f6bcfd97
BP
305
306 #---------------------------------------------
307 def OnTreeLeftDown(self, event):
308 pt = event.GetPosition();
309 item, flags = self.tree.HitTest(pt)
310 if item == self.tree.GetSelection():
311 self.SetOverview(self.tree.GetItemText(item), self.curOverview)
185d7c3e 312 event.Skip()
cf694132
RD
313
314 #---------------------------------------------
315 def OnSelChanged(self, event):
316 if self.dying:
317 return
318
5a7823f5
RD
319 item = event.GetItem()
320 itemText = self.tree.GetItemText(item)
321 self.RunDemo(itemText)
322
323
324 #---------------------------------------------
325 def RunDemo(self, itemText):
694759cf 326 os.chdir(self.cwd)
cf694132
RD
327 if self.nb.GetPageCount() == 3:
328 if self.nb.GetSelection() == 2:
329 self.nb.SetSelection(0)
330 self.nb.DeletePage(2)
331
e9159fe8 332 if itemText == self.overviewText:
cf694132 333 self.GetDemoFile('Main.py')
e9159fe8 334 self.SetOverview(self.overviewText, overview)
cf694132 335 self.nb.Refresh();
e91a9dfc 336 self.window = None
cf694132
RD
337
338 else:
339 if os.path.exists(itemText + '.py'):
9d8bd15f 340 wxBeginBusyCursor()
f6bcfd97
BP
341 wxLogMessage("Running demo %s.py..." % itemText)
342 try:
343 self.GetDemoFile(itemText + '.py')
344 module = __import__(itemText, globals())
e9159fe8 345 self.SetOverview(itemText + " Overview", module.overview)
f6bcfd97
BP
346 finally:
347 wxEndBusyCursor()
cf694132
RD
348
349 # in case runTest is modal, make sure things look right...
350 self.nb.Refresh();
351 wxYield()
352
f6bcfd97 353 self.window = module.runTest(self, self.nb, self) ###
e91a9dfc
RD
354 if self.window:
355 self.nb.AddPage(self.window, 'Demo')
dcd38683 356 wxYield()
cf694132 357 self.nb.SetSelection(2)
cf694132
RD
358
359 else:
f6bcfd97 360 self.ovr.SetPage("")
cf694132 361 self.txt.Clear()
e91a9dfc 362 self.window = None
cf694132 363
2f90df85 364
cf694132
RD
365
366 #---------------------------------------------
367 # Get the Demo files
368 def GetDemoFile(self, filename):
369 self.txt.Clear()
bb0054cd
RD
370 try:
371 self.txt.SetValue(open(filename).read())
8bf5d46e 372 except IOError:
cf694132
RD
373 self.txt.WriteText("Cannot open %s file." % filename)
374
375 self.txt.SetInsertionPoint(0)
376 self.txt.ShowPosition(0)
377
378 #---------------------------------------------
379 def SetOverview(self, name, text):
f6bcfd97
BP
380 self.curOverview = text
381 lead = text[:6]
382 if lead != '<html>' and lead != '<HTML>':
383 text = string.join(string.split(text, '\n'), '<br>')
f6bcfd97 384 self.ovr.SetPage(text)
cf694132 385 self.nb.SetPageText(0, name)
cf694132
RD
386
387 #---------------------------------------------
388 # Menu methods
c368d904 389 def OnFileExit(self, *event):
cf694132
RD
390 self.Close()
391
392
393 def OnHelpAbout(self, event):
e166644c 394 from About import MyAboutBox
ec3e670f 395 about = MyAboutBox(self)
cf694132
RD
396 about.ShowModal()
397 about.Destroy()
398
399
400 #---------------------------------------------
401 def OnCloseWindow(self, event):
402 self.dying = true
e91a9dfc 403 self.window = None
26197023 404 self.mainmenu = None
c368d904
RD
405 if hasattr(self, "tbicon"):
406 del self.tbicon
cf694132
RD
407 self.Destroy()
408
c368d904 409
cf694132
RD
410 #---------------------------------------------
411 def OnIdle(self, event):
412 if self.otherWin:
413 self.otherWin.Raise()
e91a9dfc 414 self.window = self.otherWin
cf694132
RD
415 self.otherWin = None
416
ccf691a4
RD
417 if self.showTip:
418 self.ShowTip()
419 self.showTip = false
420
421
422 #---------------------------------------------
423 def ShowTip(self):
424 try:
425 showTipText = open(opj("data/showTips")).read()
426 showTip, index = eval(showTipText)
427 except IOError:
428 showTip, index = (1, 0)
429 if showTip:
430 tp = wxCreateFileTipProvider(opj("data/tips.txt"), index)
431 showTip = wxShowTip(self, tp)
432 index = tp.GetCurrentTip()
433 open(opj("data/showTips"), "w").write(str( (showTip, index) ))
434
435
ec3e670f
RD
436 #---------------------------------------------
437 def OnDemoMenu(self, event):
f6bcfd97
BP
438 try:
439 selectedDemo = self.treeMap[self.mainmenu.GetLabel(event.GetId())]
440 except:
441 selectedDemo = None
442 if selectedDemo:
443 self.tree.SelectItem(selectedDemo)
444 self.tree.EnsureVisible(selectedDemo)
ec3e670f 445
c368d904
RD
446
447 #---------------------------------------------
448 def OnTaskBarActivate(self, evt):
449 if self.IsIconized():
450 self.Iconize(false)
451 if not self.IsShown():
452 self.Show(true)
453 self.Raise()
454
455 #---------------------------------------------
456
457 TBMENU_RESTORE = 1000
458 TBMENU_CLOSE = 1001
459
460 def OnTaskBarMenu(self, evt):
461 menu = wxMenu()
462 menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
463 menu.Append(self.TBMENU_CLOSE, "Close")
464 self.tbicon.PopupMenu(menu)
465 menu.Destroy()
466
467 #---------------------------------------------
468 def OnTaskBarClose(self, evt):
469 self.Close()
470
471 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
472 # prod the main idle handler a bit to get the window to actually close
473 wxGetApp().ProcessIdle()
474
475
f3d9dc1d
RD
476 #---------------------------------------------
477 def OnIconfiy(self, evt):
478 wxLogMessage("OnIconfiy")
479 evt.Skip()
480
481 #---------------------------------------------
482 def OnMaximize(self, evt):
483 wxLogMessage("OnMaximize")
484 evt.Skip()
485
486
487
488
cf694132
RD
489#---------------------------------------------------------------------------
490#---------------------------------------------------------------------------
491
b5a5d647
RD
492class MySplashScreen(wxSplashScreen):
493 def __init__(self):
6c5ae2d2 494 bmp = wxImage(opj("bitmaps/splash.gif")).ConvertToBitmap()
b5a5d647
RD
495 wxSplashScreen.__init__(self, bmp,
496 wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT,
497 4000, None, -1)
498 EVT_CLOSE(self, self.OnClose)
499
500 def OnClose(self, evt):
9fb56e0c 501 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
cf694132 502 frame.Show(true)
ccf691a4 503 evt.Skip() # Make sure the default handler runs too...
cf694132 504
b5a5d647
RD
505
506class MyApp(wxApp):
507 def OnInit(self):
508 """
68320e40 509 Create and show the splash screen. It will then create and show
b5a5d647
RD
510 the main frame when it is time to do so.
511 """
512 wxInitAllImageHandlers()
513 splash = MySplashScreen()
514 splash.Show()
b5a5d647
RD
515 return true
516
517
518
cf694132
RD
519#---------------------------------------------------------------------------
520
521def main():
e02c03a4 522 try:
d56cebe7 523 demoPath = os.path.dirname(__file__)
e02c03a4
RD
524 os.chdir(demoPath)
525 except:
526 pass
cf694132
RD
527 app = MyApp(0)
528 app.MainLoop()
529
530
531#---------------------------------------------------------------------------
532
533
534
f6bcfd97
BP
535overview = """<html><body>
536 <h2>Python</h2>
537
538 Python is an interpreted, interactive, object-oriented programming
539 language often compared to Tcl, Perl, Scheme, or Java.
540
541 <p> Python combines remarkable power with very clear syntax. It has
542 modules, classes, exceptions, very high level dynamic data types, and
543 dynamic typing. There are interfaces to many system calls and
544 libraries, and new built-in modules are easily written in C or
545 C++. Python is also usable as an extension language for applications
546 that need a programmable interface. <p>
547
548 <h2>wxWindows</h2>
549
550 wxWindows is a free C++ framework designed to make cross-platform
551 programming child's play. Well, almost. wxWindows 2 supports Windows
552 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
553 underway. Other ports are under consideration. <p>
554
555 wxWindows is a set of libraries that allows C++ applications to
556 compile and run on several different types of computers, with minimal
557 source code changes. There is one library per supported GUI (such as
558 Motif, or Windows). As well as providing a common API (Application
559 Programming Interface) for GUI functionality, it provides
560 functionality for accessing some commonly-used operating system
561 facilities, such as copying or deleting files. wxWindows is a
562 'framework' in the sense that it provides a lot of built-in
563 functionality, which the application can use or replace as required,
564 thus saving a great deal of coding effort. Basic data structures such
565 as strings, linked lists and hash tables are also supported.
566
567 <p>
568 <h2>wxPython</h2>
569
570 wxPython is a Python extension module that encapsulates the wxWindows
571 GUI classes. Currently it is only available for the Win32 and GTK
572 ports of wxWindows, but as soon as the other ports are brought up to
573 the same level as Win32 and GTK, it should be fairly trivial to
574 enable wxPython to be used with the new GUI.
575
576 <p>
577
578 The wxPython extension module attempts to mirror the class heiarchy
579 of wxWindows as closely as possible. This means that there is a
580 wxFrame class in wxPython that looks, smells, tastes and acts almost
581 the same as the wxFrame class in the C++ version. Unfortunately,
582 because of differences in the languages, wxPython doesn't match
583 wxWindows exactly, but the differences should be easy to absorb
584 because they are natural to Python. For example, some methods that
585 return multiple values via argument pointers in C++ will return a
586 tuple of values in Python.
587
588 <p>
589
590 There is still much to be done for wxPython, many classes still need
591 to be mirrored. Also, wxWindows is still somewhat of a moving target
592 so it is a bit of an effort just keeping wxPython up to date. On the
593 other hand, there are enough of the core classes completed that
594 useful applications can be written.
595
596 <p>
597
598 wxPython is close enough to the C++ version that the majority of
599 the wxPython documentation is actually just notes attached to the C++
600 documents that describe the places where wxPython is different. There
601 is also a series of sample programs included, and a series of
602 documentation pages that assist the programmer in getting started
603 with wxPython.
604
605 """
cf694132
RD
606
607
608#----------------------------------------------------------------------------
609#----------------------------------------------------------------------------
610
611if __name__ == '__main__':
612 main()
613
614#----------------------------------------------------------------------------
615
616
617
618
619
620
621