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