]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/Main.py
Various other tweaks and updates
[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
76bfdc78 14import sys, os, time
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 = [
4f3449b4 25 ('New since last release', ['ContextHelp',
c7e7022c 26 'PyCrust',
fea018f8 27 'PyCrustWithFilling',
6d19860f
RD
28 'VirtualListCtrl',
29 'wxListCtrl',
53fe40ba 30 'TablePrint',
0122b7e3
RD
31 'OOR',
32 'wxFindReplaceDialog',
9d37f964 33 'DrawXXXList',
79f1bf32 34 'ErrorDialogs',
729f4276 35 'wxRightTextCtrl',
846ec2f9 36 'URLDragAndDrop',
b37c7e1d 37 'wxMimeTypesManager',
c0c84fa0 38 'wxPopupWindow',
f6bcfd97 39 ]),
e395c057 40
6d19860f 41 ('Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame',
6d19860f
RD
42 'wxGrid', 'wxSashWindow',
43 'wxScrolledWindow', 'wxSplitterWindow',
44 'wxStatusBar', 'wxNotebook',
45 'wxHtmlWindow',
0122b7e3
RD
46 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',
47 ##'wxPopupWindow',
48 ]),
cf694132
RD
49
50 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
51 'wxSingleChoiceDialog', 'wxTextEntryDialog',
52 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
0122b7e3
RD
53 'wxMessageDialog', 'wxProgressDialog', 'wxFindReplaceDialog',
54 ]),
cf694132
RD
55
56 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
57 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
f6bcfd97
BP
58 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
59 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
d1679124 60 'wxCalendarCtrl', 'wxToggleButton',
6999b0d8 61 ]),
cf694132 62
4f3449b4 63 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource']),
cf694132 64
846ec2f9
RD
65 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'URLDragAndDrop',
66 'FontEnumerator',
b1462dfa 67 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
9b3d3bc4 68 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
f6bcfd97
BP
69 'PythonEvents', 'Threads',
70 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
493f1553 71 'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
b37c7e1d 72 'wxJoystick', 'DrawXXXList', 'ErrorDialogs', 'wxMimeTypesManager',
f6bcfd97 73 ]),
cf694132 74
e0473f5f 75 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
f0261a72 76 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
c7e7022c 77 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
c368d904 78 'FileBrowseButton', 'GenericButtons', 'wxEditor',
c7e7022c 79 'ColourSelect', 'ImageBrowser',
53fe40ba 80 'infoframe', 'ColourDB', 'PyCrust', 'TablePrint',
729f4276 81 'wxRightTextCtrl',
c368d904 82 ]),
cf694132 83
8bf5d46e 84 ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']),
cf694132
RD
85
86 ]
87
88#---------------------------------------------------------------------------
89
76bfdc78
RD
90class MyLog(wxPyLog):
91 def __init__(self, textCtrl, logTime=0):
92 wxPyLog.__init__(self)
93 self.tc = textCtrl
94 self.logTime = logTime
95
96 def DoLogString(self, message, timeStamp):
97 if self.logTime:
98 message = time.strftime("%X", time.localtime(timeStamp)) + \
99 ": " + message
100 self.tc.AppendText(message + '\n')
101
102
103#---------------------------------------------------------------------------
104
cf694132 105class wxPythonDemo(wxFrame):
c368d904 106
cf694132 107 def __init__(self, parent, id, title):
f6bcfd97
BP
108 wxFrame.__init__(self, parent, -1, title, size = (800, 600),
109 style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE)
2f90df85 110
694759cf 111 self.cwd = os.getcwd()
3ca6a5f0 112 self.curOverview = ""
694759cf 113
b6962846
RD
114 if 1:
115 icon = wxIconFromXPMData(images.getMondrianData())
116 else:
117 # another way to do it
118 bmp = images.getMondrianBitmap()
119 icon = wxEmptyIcon()
120 icon.CopyFromBitmap(bmp)
121
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 |
193 wxTR_HAS_VARIABLE_ROW_HEIGHT |
194 wxSUNKEN_BORDER)
195 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
196 root = self.tree.AddRoot("Overview")
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))
221 self.nb.AddPage(self.ovr, "Overview")
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
RD
225 self.ovr = wxHtmlWindow(panel, -1, size=(400, 400))
226 self.nb.AddPage(panel, "Overview")
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
RD
234
235 self.SetOverview("Overview", 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)
257 splitter2.SetSashPosition(450, true)
258 splitter2.SetMinimumPaneSize(20)
cf694132 259
f6bcfd97
BP
260 splitter.SplitVertically(self.tree, splitter2)
261 splitter.SetSashPosition(180, true)
262 splitter.SetMinimumPaneSize(20)
cf694132 263
cf694132 264
bb0054cd
RD
265 # select initial items
266 self.nb.SetSelection(0)
f6bcfd97 267 self.tree.SelectItem(root)
ec3e670f
RD
268
269 if len(sys.argv) == 2:
270 try:
271 selectedDemo = self.treeMap[sys.argv[1]]
272 except:
273 selectedDemo = None
f6bcfd97 274 if selectedDemo:
ec3e670f
RD
275 self.tree.SelectItem(selectedDemo)
276 self.tree.EnsureVisible(selectedDemo)
277
bb0054cd 278
f6bcfd97 279 wxLogMessage('window handle: %s' % self.GetHandle())
2abc0a0f
RD
280
281
cf694132
RD
282 #---------------------------------------------
283 def WriteText(self, text):
f6bcfd97
BP
284 if text[-1:] == '\n':
285 text = text[:-1]
286 wxLogMessage(text)
287
cf694132
RD
288
289 def write(self, txt):
290 self.WriteText(txt)
291
292 #---------------------------------------------
293 def OnItemExpanded(self, event):
294 item = event.GetItem()
f6bcfd97 295 wxLogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
c368d904 296 event.Skip()
cf694132
RD
297
298 #---------------------------------------------
299 def OnItemCollapsed(self, event):
300 item = event.GetItem()
f6bcfd97 301 wxLogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
c368d904 302 event.Skip()
f6bcfd97
BP
303
304 #---------------------------------------------
305 def OnTreeLeftDown(self, event):
306 pt = event.GetPosition();
307 item, flags = self.tree.HitTest(pt)
308 if item == self.tree.GetSelection():
309 self.SetOverview(self.tree.GetItemText(item), self.curOverview)
185d7c3e 310 event.Skip()
cf694132
RD
311
312 #---------------------------------------------
313 def OnSelChanged(self, event):
314 if self.dying:
315 return
316
5a7823f5
RD
317 item = event.GetItem()
318 itemText = self.tree.GetItemText(item)
319 self.RunDemo(itemText)
320
321
322 #---------------------------------------------
323 def RunDemo(self, itemText):
694759cf 324 os.chdir(self.cwd)
cf694132
RD
325 if self.nb.GetPageCount() == 3:
326 if self.nb.GetSelection() == 2:
327 self.nb.SetSelection(0)
328 self.nb.DeletePage(2)
329
cf694132
RD
330 if itemText == 'Overview':
331 self.GetDemoFile('Main.py')
332 self.SetOverview('Overview', overview)
cf694132 333 self.nb.Refresh();
e91a9dfc 334 self.window = None
cf694132
RD
335
336 else:
337 if os.path.exists(itemText + '.py'):
9d8bd15f 338 wxBeginBusyCursor()
f6bcfd97
BP
339 wxLogMessage("Running demo %s.py..." % itemText)
340 try:
341 self.GetDemoFile(itemText + '.py')
342 module = __import__(itemText, globals())
343 self.SetOverview(itemText, module.overview)
344 finally:
345 wxEndBusyCursor()
cf694132
RD
346
347 # in case runTest is modal, make sure things look right...
348 self.nb.Refresh();
349 wxYield()
350
f6bcfd97 351 self.window = module.runTest(self, self.nb, self) ###
e91a9dfc
RD
352 if self.window:
353 self.nb.AddPage(self.window, 'Demo')
dcd38683 354 wxYield()
cf694132 355 self.nb.SetSelection(2)
cf694132
RD
356
357 else:
f6bcfd97 358 self.ovr.SetPage("")
cf694132 359 self.txt.Clear()
e91a9dfc 360 self.window = None
cf694132 361
2f90df85 362
cf694132
RD
363
364 #---------------------------------------------
365 # Get the Demo files
366 def GetDemoFile(self, filename):
367 self.txt.Clear()
bb0054cd
RD
368 try:
369 self.txt.SetValue(open(filename).read())
8bf5d46e 370 except IOError:
cf694132
RD
371 self.txt.WriteText("Cannot open %s file." % filename)
372
373 self.txt.SetInsertionPoint(0)
374 self.txt.ShowPosition(0)
375
376 #---------------------------------------------
377 def SetOverview(self, name, text):
f6bcfd97
BP
378 self.curOverview = text
379 lead = text[:6]
380 if lead != '<html>' and lead != '<HTML>':
381 text = string.join(string.split(text, '\n'), '<br>')
382 #text = '<font size="-1"><pre>' + text + '</pre></font>'
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
472class MyApp(wxApp):
473 def OnInit(self):
f6bcfd97 474 wxInitAllImageHandlers()
9fb56e0c
RD
475
476 self.splash = SplashScreen(None, bitmapfile='bitmaps/splash.gif',
477 duration=4000, callback=self.AfterSplash)
478 self.splash.Show(true)
479 wxYield()
480 return true
481
f6bcfd97 482
9fb56e0c
RD
483 def AfterSplash(self):
484 self.splash.Close(true)
485 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
cf694132
RD
486 frame.Show(true)
487 self.SetTopWindow(frame)
f6bcfd97
BP
488 self.ShowTip(frame)
489
490
491 def ShowTip(self, frame):
492 try:
493 showTipText = open("data/showTips").read()
494 showTip, index = eval(showTipText)
495 except IOError:
496 showTip, index = (1, 0)
c368d904 497 #print showTip, index
f6bcfd97
BP
498 if showTip:
499 tp = wxCreateFileTipProvider("data/tips.txt", index)
500 showTip = wxShowTip(frame, tp)
501 index = tp.GetCurrentTip()
502 open("data/showTips", "w").write(str( (showTip, index) ))
503
cf694132
RD
504
505#---------------------------------------------------------------------------
506
507def main():
e02c03a4 508 try:
d56cebe7 509 demoPath = os.path.dirname(__file__)
e02c03a4
RD
510 os.chdir(demoPath)
511 except:
512 pass
cf694132
RD
513 app = MyApp(0)
514 app.MainLoop()
515
516
517#---------------------------------------------------------------------------
518
519
520
f6bcfd97
BP
521overview = """<html><body>
522 <h2>Python</h2>
523
524 Python is an interpreted, interactive, object-oriented programming
525 language often compared to Tcl, Perl, Scheme, or Java.
526
527 <p> Python combines remarkable power with very clear syntax. It has
528 modules, classes, exceptions, very high level dynamic data types, and
529 dynamic typing. There are interfaces to many system calls and
530 libraries, and new built-in modules are easily written in C or
531 C++. Python is also usable as an extension language for applications
532 that need a programmable interface. <p>
533
534 <h2>wxWindows</h2>
535
536 wxWindows is a free C++ framework designed to make cross-platform
537 programming child's play. Well, almost. wxWindows 2 supports Windows
538 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
539 underway. Other ports are under consideration. <p>
540
541 wxWindows is a set of libraries that allows C++ applications to
542 compile and run on several different types of computers, with minimal
543 source code changes. There is one library per supported GUI (such as
544 Motif, or Windows). As well as providing a common API (Application
545 Programming Interface) for GUI functionality, it provides
546 functionality for accessing some commonly-used operating system
547 facilities, such as copying or deleting files. wxWindows is a
548 'framework' in the sense that it provides a lot of built-in
549 functionality, which the application can use or replace as required,
550 thus saving a great deal of coding effort. Basic data structures such
551 as strings, linked lists and hash tables are also supported.
552
553 <p>
554 <h2>wxPython</h2>
555
556 wxPython is a Python extension module that encapsulates the wxWindows
557 GUI classes. Currently it is only available for the Win32 and GTK
558 ports of wxWindows, but as soon as the other ports are brought up to
559 the same level as Win32 and GTK, it should be fairly trivial to
560 enable wxPython to be used with the new GUI.
561
562 <p>
563
564 The wxPython extension module attempts to mirror the class heiarchy
565 of wxWindows as closely as possible. This means that there is a
566 wxFrame class in wxPython that looks, smells, tastes and acts almost
567 the same as the wxFrame class in the C++ version. Unfortunately,
568 because of differences in the languages, wxPython doesn't match
569 wxWindows exactly, but the differences should be easy to absorb
570 because they are natural to Python. For example, some methods that
571 return multiple values via argument pointers in C++ will return a
572 tuple of values in Python.
573
574 <p>
575
576 There is still much to be done for wxPython, many classes still need
577 to be mirrored. Also, wxWindows is still somewhat of a moving target
578 so it is a bit of an effort just keeping wxPython up to date. On the
579 other hand, there are enough of the core classes completed that
580 useful applications can be written.
581
582 <p>
583
584 wxPython is close enough to the C++ version that the majority of
585 the wxPython documentation is actually just notes attached to the C++
586 documents that describe the places where wxPython is different. There
587 is also a series of sample programs included, and a series of
588 documentation pages that assist the programmer in getting started
589 with wxPython.
590
591 """
cf694132
RD
592
593
594#----------------------------------------------------------------------------
595#----------------------------------------------------------------------------
596
597if __name__ == '__main__':
598 main()
599
600#----------------------------------------------------------------------------
601
602
603
604
605
606
607