]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/Main.py
A little different fix for how to delay the call to __wxCleanup
[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 *
9fb56e0c 16from wxPython.lib.splashscreen import SplashScreen
f6bcfd97 17from wxPython.html import wxHtmlWindow
cf694132 18
96bfd053
RD
19import images
20
cf694132
RD
21#---------------------------------------------------------------------------
22
23
24_treeList = [
68320e40 25 ('New since last release', ['wxGenericDirCtrl',
f6bcfd97 26 ]),
e395c057 27
6d19860f 28 ('Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame',
6d19860f
RD
29 'wxGrid', 'wxSashWindow',
30 'wxScrolledWindow', 'wxSplitterWindow',
31 'wxStatusBar', 'wxNotebook',
32 'wxHtmlWindow',
0122b7e3 33 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',
a57d56d6 34 'wxPopupWindow',
ebf4302c 35 'wxDynamicSashWindow',
0122b7e3 36 ]),
cf694132
RD
37
38 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
39 'wxSingleChoiceDialog', 'wxTextEntryDialog',
40 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
0122b7e3
RD
41 'wxMessageDialog', 'wxProgressDialog', 'wxFindReplaceDialog',
42 ]),
cf694132
RD
43
44 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
68320e40
RD
45 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'VirtualListCtrl',
46 'wxTextCtrl',
f6bcfd97
BP
47 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
48 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
d1679124 49 'wxCalendarCtrl', 'wxToggleButton',
950e7faf 50 'wxEditableListBox', 'wxLEDNumberCtrl',
6999b0d8 51 ]),
cf694132 52
4f3449b4 53 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource']),
cf694132 54
846ec2f9
RD
55 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'URLDragAndDrop',
56 'FontEnumerator',
b1462dfa 57 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
9b3d3bc4 58 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
f6bcfd97
BP
59 'PythonEvents', 'Threads',
60 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
493f1553 61 'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
b37c7e1d 62 'wxJoystick', 'DrawXXXList', 'ErrorDialogs', 'wxMimeTypesManager',
68320e40 63 'ContextHelp', 'SplitTree',
f6bcfd97 64 ]),
cf694132 65
e0473f5f 66 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
f0261a72 67 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
c7e7022c 68 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
c368d904 69 'FileBrowseButton', 'GenericButtons', 'wxEditor',
c7e7022c 70 'ColourSelect', 'ImageBrowser',
68320e40
RD
71 'infoframe', 'ColourDB', 'PyCrust', 'PyCrustWithFilling',
72 'TablePrint',
729f4276 73 'wxRightTextCtrl',
c368d904 74 ]),
cf694132 75
611dc22c
RD
76 ('Cool Contribs', ['pyTree', 'hangman',
77 #'SlashDot',
78 'XMLtreeview'
79 ]),
cf694132
RD
80
81 ]
82
83#---------------------------------------------------------------------------
84
76bfdc78
RD
85class MyLog(wxPyLog):
86 def __init__(self, textCtrl, logTime=0):
87 wxPyLog.__init__(self)
88 self.tc = textCtrl
89 self.logTime = logTime
90
91 def DoLogString(self, message, timeStamp):
92 if self.logTime:
93 message = time.strftime("%X", time.localtime(timeStamp)) + \
94 ": " + message
95 self.tc.AppendText(message + '\n')
96
97
6c5ae2d2
RD
98#---------------------------------------------------------------------------
99
100def opj(path):
101 """Convert paths to the platform-specific separator"""
102 return apply(os.path.join, tuple(string.split(path, '/')))
103
104
76bfdc78
RD
105#---------------------------------------------------------------------------
106
cf694132 107class wxPythonDemo(wxFrame):
c368d904 108
cf694132 109 def __init__(self, parent, id, title):
f6bcfd97
BP
110 wxFrame.__init__(self, parent, -1, title, size = (800, 600),
111 style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE)
2f90df85 112
694759cf 113 self.cwd = os.getcwd()
3ca6a5f0 114 self.curOverview = ""
694759cf 115
b6962846
RD
116 if 1:
117 icon = wxIconFromXPMData(images.getMondrianData())
118 else:
119 # another way to do it
120 bmp = images.getMondrianBitmap()
121 icon = wxEmptyIcon()
122 icon.CopyFromBitmap(bmp)
123
96bfd053 124 self.SetIcon(icon)
c368d904 125
96bfd053 126 if wxPlatform == '__WXMSW__':
c368d904
RD
127 # setup a taskbar icon, and catch some events from it
128 self.tbicon = wxTaskBarIcon()
129 self.tbicon.SetIcon(icon, "wxPython Demo")
130 EVT_TASKBAR_LEFT_DCLICK(self.tbicon, self.OnTaskBarActivate)
131 EVT_TASKBAR_RIGHT_UP(self.tbicon, self.OnTaskBarMenu)
132 EVT_MENU(self.tbicon, self.TBMENU_RESTORE, self.OnTaskBarActivate)
133 EVT_MENU(self.tbicon, self.TBMENU_CLOSE, self.OnTaskBarClose)
134
cf694132
RD
135
136 self.otherWin = None
137 EVT_IDLE(self, self.OnIdle)
f6bcfd97 138 EVT_CLOSE(self, self.OnCloseWindow)
f3d9dc1d
RD
139 EVT_ICONIZE(self, self.OnIconfiy)
140 EVT_MAXIMIZE(self, self.OnMaximize)
cf694132
RD
141
142 self.Centre(wxBOTH)
143 self.CreateStatusBar(1, wxST_SIZEGRIP)
5a7823f5 144
f6bcfd97
BP
145 splitter = wxSplitterWindow(self, -1, style=wxNO_3D|wxSP_3D)
146 splitter2 = wxSplitterWindow(splitter, -1, style=wxNO_3D|wxSP_3D)
5a7823f5 147
d56cebe7
RD
148 def EmptyHandler(evt): pass
149 EVT_ERASE_BACKGROUND(splitter, EmptyHandler)
150 EVT_ERASE_BACKGROUND(splitter2, EmptyHandler)
cf694132 151
b1cfebd9 152 # Prevent TreeCtrl from displaying all items after destruction when true
cf694132
RD
153 self.dying = false
154
155 # Make a File menu
156 self.mainmenu = wxMenuBar()
157 menu = wxMenu()
2f90df85 158 exitID = wxNewId()
f0261a72 159 menu.Append(exitID, 'E&xit\tAlt-X', 'Get the heck outta here!')
2f90df85 160 EVT_MENU(self, exitID, self.OnFileExit)
cf694132
RD
161 self.mainmenu.Append(menu, '&File')
162
ec3e670f
RD
163 # Make a Demo menu
164 menu = wxMenu()
165 for item in _treeList:
166 submenu = wxMenu()
167 for childItem in item[1]:
168 mID = wxNewId()
169 submenu.Append(mID, childItem)
170 EVT_MENU(self, mID, self.OnDemoMenu)
171 menu.AppendMenu(wxNewId(), item[0], submenu)
172 self.mainmenu.Append(menu, '&Demo')
173
174
cf694132 175 # Make a Help menu
2f90df85 176 helpID = wxNewId()
cf694132 177 menu = wxMenu()
2f90df85
RD
178 menu.Append(helpID, '&About\tCtrl-H', 'wxPython RULES!!!')
179 EVT_MENU(self, helpID, self.OnHelpAbout)
cf694132
RD
180 self.mainmenu.Append(menu, '&Help')
181 self.SetMenuBar(self.mainmenu)
182
2f90df85 183 # set the menu accellerator table...
f0261a72 184 aTable = wxAcceleratorTable([(wxACCEL_ALT, ord('X'), exitID),
2f90df85
RD
185 (wxACCEL_CTRL, ord('H'), helpID)])
186 self.SetAcceleratorTable(aTable)
187
bb0054cd 188
cf694132 189 # Create a TreeCtrl
f6bcfd97
BP
190 tID = wxNewId()
191 self.treeMap = {}
192 self.tree = wxTreeCtrl(splitter, tID,
193 style=wxTR_HAS_BUTTONS |
194 wxTR_EDIT_LABELS |
195 wxTR_HAS_VARIABLE_ROW_HEIGHT |
196 wxSUNKEN_BORDER)
197 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
198 root = self.tree.AddRoot("Overview")
199 firstChild = None
200 for item in _treeList:
201 child = self.tree.AppendItem(root, item[0])
202 if not firstChild: firstChild = child
203 for childItem in item[1]:
204 theDemo = self.tree.AppendItem(child, childItem)
205 self.treeMap[childItem] = theDemo
206
207 self.tree.Expand(root)
208 self.tree.Expand(firstChild)
209 EVT_TREE_ITEM_EXPANDED (self.tree, tID, self.OnItemExpanded)
210 EVT_TREE_ITEM_COLLAPSED (self.tree, tID, self.OnItemCollapsed)
211 EVT_TREE_SEL_CHANGED (self.tree, tID, self.OnSelChanged)
212 EVT_LEFT_DOWN (self.tree, self.OnTreeLeftDown)
cf694132 213
cf694132 214 # Create a Notebook
d56cebe7 215 self.nb = wxNotebook(splitter2, -1, style=wxCLIP_CHILDREN)
cf694132 216
c368d904
RD
217 # Set up a wxHtmlWindow on the Overview Notebook page
218 # we put it in a panel first because there seems to be a
219 # refresh bug of some sort (wxGTK) when it is directly in
220 # the notebook...
221 if 0: # the old way
222 self.ovr = wxHtmlWindow(self.nb, -1, size=(400, 400))
223 self.nb.AddPage(self.ovr, "Overview")
224
e87269a7 225 else: # hopefully I can remove this hacky code soon, see bug #216861
d56cebe7 226 panel = wxPanel(self.nb, -1, style=wxCLIP_CHILDREN)
c368d904
RD
227 self.ovr = wxHtmlWindow(panel, -1, size=(400, 400))
228 self.nb.AddPage(panel, "Overview")
229
230 def OnOvrSize(evt, ovr=self.ovr):
231 ovr.SetSize(evt.GetSize())
232
233 EVT_SIZE(panel, OnOvrSize)
d56cebe7
RD
234 EVT_ERASE_BACKGROUND(panel, EmptyHandler)
235
c368d904
RD
236
237 self.SetOverview("Overview", overview)
cf694132
RD
238
239
240 # Set up a TextCtrl on the Demo Code Notebook page
efc5f224
RD
241 self.txt = wxTextCtrl(self.nb, -1,
242 style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
cf694132
RD
243 self.nb.AddPage(self.txt, "Demo Code")
244
245
cf694132 246 # Set up a log on the View Log Notebook page
f6bcfd97 247 self.log = wxTextCtrl(splitter2, -1,
efc5f224 248 style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
f6bcfd97 249 # Set the wxWindows log target to be this textctrl
76bfdc78
RD
250 #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
251 wxLog_SetActiveTarget(MyLog(self.log))
cf694132
RD
252
253
5a7823f5 254
f6bcfd97 255 self.Show(true)
5a7823f5 256
f6bcfd97
BP
257 # add the windows to the splitter and split it.
258 splitter2.SplitHorizontally(self.nb, self.log)
259 splitter2.SetSashPosition(450, true)
260 splitter2.SetMinimumPaneSize(20)
cf694132 261
f6bcfd97
BP
262 splitter.SplitVertically(self.tree, splitter2)
263 splitter.SetSashPosition(180, true)
264 splitter.SetMinimumPaneSize(20)
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
cf694132
RD
332 if itemText == 'Overview':
333 self.GetDemoFile('Main.py')
334 self.SetOverview('Overview', 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())
345 self.SetOverview(itemText, module.overview)
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
ec3e670f
RD
417 #---------------------------------------------
418 def OnDemoMenu(self, event):
f6bcfd97
BP
419 try:
420 selectedDemo = self.treeMap[self.mainmenu.GetLabel(event.GetId())]
421 except:
422 selectedDemo = None
423 if selectedDemo:
424 self.tree.SelectItem(selectedDemo)
425 self.tree.EnsureVisible(selectedDemo)
ec3e670f 426
c368d904
RD
427
428 #---------------------------------------------
429 def OnTaskBarActivate(self, evt):
430 if self.IsIconized():
431 self.Iconize(false)
432 if not self.IsShown():
433 self.Show(true)
434 self.Raise()
435
436 #---------------------------------------------
437
438 TBMENU_RESTORE = 1000
439 TBMENU_CLOSE = 1001
440
441 def OnTaskBarMenu(self, evt):
442 menu = wxMenu()
443 menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
444 menu.Append(self.TBMENU_CLOSE, "Close")
445 self.tbicon.PopupMenu(menu)
446 menu.Destroy()
447
448 #---------------------------------------------
449 def OnTaskBarClose(self, evt):
450 self.Close()
451
452 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
453 # prod the main idle handler a bit to get the window to actually close
454 wxGetApp().ProcessIdle()
455
456
f3d9dc1d
RD
457 #---------------------------------------------
458 def OnIconfiy(self, evt):
459 wxLogMessage("OnIconfiy")
460 evt.Skip()
461
462 #---------------------------------------------
463 def OnMaximize(self, evt):
464 wxLogMessage("OnMaximize")
465 evt.Skip()
466
467
468
469
cf694132
RD
470#---------------------------------------------------------------------------
471#---------------------------------------------------------------------------
472
b5a5d647
RD
473class MySplashScreen(wxSplashScreen):
474 def __init__(self):
6c5ae2d2 475 bmp = wxImage(opj("bitmaps/splash.gif")).ConvertToBitmap()
b5a5d647
RD
476 wxSplashScreen.__init__(self, bmp,
477 wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT,
478 4000, None, -1)
479 EVT_CLOSE(self, self.OnClose)
480
481 def OnClose(self, evt):
9fb56e0c 482 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
cf694132 483 frame.Show(true)
f6bcfd97 484 self.ShowTip(frame)
b5a5d647 485 evt.Skip()
f6bcfd97
BP
486
487 def ShowTip(self, frame):
488 try:
6c5ae2d2 489 showTipText = open(opj("data/showTips")).read()
f6bcfd97
BP
490 showTip, index = eval(showTipText)
491 except IOError:
492 showTip, index = (1, 0)
f6bcfd97 493 if showTip:
6c5ae2d2 494 tp = wxCreateFileTipProvider(opj("data/tips.txt"), index)
f6bcfd97
BP
495 showTip = wxShowTip(frame, tp)
496 index = tp.GetCurrentTip()
6c5ae2d2 497 open(opj("data/showTips"), "w").write(str( (showTip, index) ))
f6bcfd97 498
cf694132 499
b5a5d647
RD
500
501class MyApp(wxApp):
502 def OnInit(self):
503 """
68320e40 504 Create and show the splash screen. It will then create and show
b5a5d647
RD
505 the main frame when it is time to do so.
506 """
507 wxInitAllImageHandlers()
508 splash = MySplashScreen()
509 splash.Show()
510 wxYield()
511 return true
512
513
514
cf694132
RD
515#---------------------------------------------------------------------------
516
517def main():
e02c03a4 518 try:
d56cebe7 519 demoPath = os.path.dirname(__file__)
e02c03a4
RD
520 os.chdir(demoPath)
521 except:
522 pass
cf694132
RD
523 app = MyApp(0)
524 app.MainLoop()
525
526
527#---------------------------------------------------------------------------
528
529
530
f6bcfd97
BP
531overview = """<html><body>
532 <h2>Python</h2>
533
534 Python is an interpreted, interactive, object-oriented programming
535 language often compared to Tcl, Perl, Scheme, or Java.
536
537 <p> Python combines remarkable power with very clear syntax. It has
538 modules, classes, exceptions, very high level dynamic data types, and
539 dynamic typing. There are interfaces to many system calls and
540 libraries, and new built-in modules are easily written in C or
541 C++. Python is also usable as an extension language for applications
542 that need a programmable interface. <p>
543
544 <h2>wxWindows</h2>
545
546 wxWindows is a free C++ framework designed to make cross-platform
547 programming child's play. Well, almost. wxWindows 2 supports Windows
548 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
549 underway. Other ports are under consideration. <p>
550
551 wxWindows is a set of libraries that allows C++ applications to
552 compile and run on several different types of computers, with minimal
553 source code changes. There is one library per supported GUI (such as
554 Motif, or Windows). As well as providing a common API (Application
555 Programming Interface) for GUI functionality, it provides
556 functionality for accessing some commonly-used operating system
557 facilities, such as copying or deleting files. wxWindows is a
558 'framework' in the sense that it provides a lot of built-in
559 functionality, which the application can use or replace as required,
560 thus saving a great deal of coding effort. Basic data structures such
561 as strings, linked lists and hash tables are also supported.
562
563 <p>
564 <h2>wxPython</h2>
565
566 wxPython is a Python extension module that encapsulates the wxWindows
567 GUI classes. Currently it is only available for the Win32 and GTK
568 ports of wxWindows, but as soon as the other ports are brought up to
569 the same level as Win32 and GTK, it should be fairly trivial to
570 enable wxPython to be used with the new GUI.
571
572 <p>
573
574 The wxPython extension module attempts to mirror the class heiarchy
575 of wxWindows as closely as possible. This means that there is a
576 wxFrame class in wxPython that looks, smells, tastes and acts almost
577 the same as the wxFrame class in the C++ version. Unfortunately,
578 because of differences in the languages, wxPython doesn't match
579 wxWindows exactly, but the differences should be easy to absorb
580 because they are natural to Python. For example, some methods that
581 return multiple values via argument pointers in C++ will return a
582 tuple of values in Python.
583
584 <p>
585
586 There is still much to be done for wxPython, many classes still need
587 to be mirrored. Also, wxWindows is still somewhat of a moving target
588 so it is a bit of an effort just keeping wxPython up to date. On the
589 other hand, there are enough of the core classes completed that
590 useful applications can be written.
591
592 <p>
593
594 wxPython is close enough to the C++ version that the majority of
595 the wxPython documentation is actually just notes attached to the C++
596 documents that describe the places where wxPython is different. There
597 is also a series of sample programs included, and a series of
598 documentation pages that assist the programmer in getting started
599 with wxPython.
600
601 """
cf694132
RD
602
603
604#----------------------------------------------------------------------------
605#----------------------------------------------------------------------------
606
607if __name__ == '__main__':
608 main()
609
610#----------------------------------------------------------------------------
611
612
613
614
615
616
617