]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/Main.py
Added tooltips to the buttons in the wxEditableListBox
[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',
ebf4302c 39 'wxDynamicSashWindow',
f6bcfd97 40 ]),
e395c057 41
6d19860f 42 ('Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame',
6d19860f
RD
43 'wxGrid', 'wxSashWindow',
44 'wxScrolledWindow', 'wxSplitterWindow',
45 'wxStatusBar', 'wxNotebook',
46 'wxHtmlWindow',
0122b7e3 47 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',
a57d56d6 48 'wxPopupWindow',
ebf4302c 49 'wxDynamicSashWindow',
0122b7e3 50 ]),
cf694132
RD
51
52 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
53 'wxSingleChoiceDialog', 'wxTextEntryDialog',
54 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
0122b7e3
RD
55 'wxMessageDialog', 'wxProgressDialog', 'wxFindReplaceDialog',
56 ]),
cf694132
RD
57
58 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
59 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
f6bcfd97
BP
60 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
61 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
d1679124 62 'wxCalendarCtrl', 'wxToggleButton',
6999b0d8 63 ]),
cf694132 64
4f3449b4 65 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource']),
cf694132 66
846ec2f9
RD
67 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'URLDragAndDrop',
68 'FontEnumerator',
b1462dfa 69 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
9b3d3bc4 70 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
f6bcfd97
BP
71 'PythonEvents', 'Threads',
72 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
493f1553 73 'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
b37c7e1d 74 'wxJoystick', 'DrawXXXList', 'ErrorDialogs', 'wxMimeTypesManager',
f6bcfd97 75 ]),
cf694132 76
e0473f5f 77 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
f0261a72 78 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
c7e7022c 79 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
c368d904 80 'FileBrowseButton', 'GenericButtons', 'wxEditor',
c7e7022c 81 'ColourSelect', 'ImageBrowser',
53fe40ba 82 'infoframe', 'ColourDB', 'PyCrust', 'TablePrint',
729f4276 83 'wxRightTextCtrl',
c368d904 84 ]),
cf694132 85
8bf5d46e 86 ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']),
cf694132
RD
87
88 ]
89
90#---------------------------------------------------------------------------
91
76bfdc78
RD
92class MyLog(wxPyLog):
93 def __init__(self, textCtrl, logTime=0):
94 wxPyLog.__init__(self)
95 self.tc = textCtrl
96 self.logTime = logTime
97
98 def DoLogString(self, message, timeStamp):
99 if self.logTime:
100 message = time.strftime("%X", time.localtime(timeStamp)) + \
101 ": " + message
102 self.tc.AppendText(message + '\n')
103
104
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>')
384 #text = '<font size="-1"><pre>' + text + '</pre></font>'
385 self.ovr.SetPage(text)
cf694132 386 self.nb.SetPageText(0, name)
cf694132
RD
387
388 #---------------------------------------------
389 # Menu methods
c368d904 390 def OnFileExit(self, *event):
cf694132
RD
391 self.Close()
392
393
394 def OnHelpAbout(self, event):
e166644c 395 from About import MyAboutBox
ec3e670f 396 about = MyAboutBox(self)
cf694132
RD
397 about.ShowModal()
398 about.Destroy()
399
400
401 #---------------------------------------------
402 def OnCloseWindow(self, event):
403 self.dying = true
e91a9dfc 404 self.window = None
26197023 405 self.mainmenu = None
c368d904
RD
406 if hasattr(self, "tbicon"):
407 del self.tbicon
cf694132
RD
408 self.Destroy()
409
c368d904 410
cf694132
RD
411 #---------------------------------------------
412 def OnIdle(self, event):
413 if self.otherWin:
414 self.otherWin.Raise()
e91a9dfc 415 self.window = self.otherWin
cf694132
RD
416 self.otherWin = None
417
ec3e670f
RD
418 #---------------------------------------------
419 def OnDemoMenu(self, event):
f6bcfd97
BP
420 try:
421 selectedDemo = self.treeMap[self.mainmenu.GetLabel(event.GetId())]
422 except:
423 selectedDemo = None
424 if selectedDemo:
425 self.tree.SelectItem(selectedDemo)
426 self.tree.EnsureVisible(selectedDemo)
ec3e670f 427
c368d904
RD
428
429 #---------------------------------------------
430 def OnTaskBarActivate(self, evt):
431 if self.IsIconized():
432 self.Iconize(false)
433 if not self.IsShown():
434 self.Show(true)
435 self.Raise()
436
437 #---------------------------------------------
438
439 TBMENU_RESTORE = 1000
440 TBMENU_CLOSE = 1001
441
442 def OnTaskBarMenu(self, evt):
443 menu = wxMenu()
444 menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
445 menu.Append(self.TBMENU_CLOSE, "Close")
446 self.tbicon.PopupMenu(menu)
447 menu.Destroy()
448
449 #---------------------------------------------
450 def OnTaskBarClose(self, evt):
451 self.Close()
452
453 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
454 # prod the main idle handler a bit to get the window to actually close
455 wxGetApp().ProcessIdle()
456
457
f3d9dc1d
RD
458 #---------------------------------------------
459 def OnIconfiy(self, evt):
460 wxLogMessage("OnIconfiy")
461 evt.Skip()
462
463 #---------------------------------------------
464 def OnMaximize(self, evt):
465 wxLogMessage("OnMaximize")
466 evt.Skip()
467
468
469
470
cf694132
RD
471#---------------------------------------------------------------------------
472#---------------------------------------------------------------------------
473
474class MyApp(wxApp):
475 def OnInit(self):
f6bcfd97 476 wxInitAllImageHandlers()
9fb56e0c
RD
477
478 self.splash = SplashScreen(None, bitmapfile='bitmaps/splash.gif',
479 duration=4000, callback=self.AfterSplash)
480 self.splash.Show(true)
481 wxYield()
482 return true
483
f6bcfd97 484
9fb56e0c
RD
485 def AfterSplash(self):
486 self.splash.Close(true)
487 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
cf694132
RD
488 frame.Show(true)
489 self.SetTopWindow(frame)
f6bcfd97
BP
490 self.ShowTip(frame)
491
492
493 def ShowTip(self, frame):
494 try:
495 showTipText = open("data/showTips").read()
496 showTip, index = eval(showTipText)
497 except IOError:
498 showTip, index = (1, 0)
c368d904 499 #print showTip, index
f6bcfd97
BP
500 if showTip:
501 tp = wxCreateFileTipProvider("data/tips.txt", index)
502 showTip = wxShowTip(frame, tp)
503 index = tp.GetCurrentTip()
504 open("data/showTips", "w").write(str( (showTip, index) ))
505
cf694132
RD
506
507#---------------------------------------------------------------------------
508
509def main():
e02c03a4 510 try:
d56cebe7 511 demoPath = os.path.dirname(__file__)
e02c03a4
RD
512 os.chdir(demoPath)
513 except:
514 pass
cf694132
RD
515 app = MyApp(0)
516 app.MainLoop()
517
518
519#---------------------------------------------------------------------------
520
521
522
f6bcfd97
BP
523overview = """<html><body>
524 <h2>Python</h2>
525
526 Python is an interpreted, interactive, object-oriented programming
527 language often compared to Tcl, Perl, Scheme, or Java.
528
529 <p> Python combines remarkable power with very clear syntax. It has
530 modules, classes, exceptions, very high level dynamic data types, and
531 dynamic typing. There are interfaces to many system calls and
532 libraries, and new built-in modules are easily written in C or
533 C++. Python is also usable as an extension language for applications
534 that need a programmable interface. <p>
535
536 <h2>wxWindows</h2>
537
538 wxWindows is a free C++ framework designed to make cross-platform
539 programming child's play. Well, almost. wxWindows 2 supports Windows
540 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
541 underway. Other ports are under consideration. <p>
542
543 wxWindows is a set of libraries that allows C++ applications to
544 compile and run on several different types of computers, with minimal
545 source code changes. There is one library per supported GUI (such as
546 Motif, or Windows). As well as providing a common API (Application
547 Programming Interface) for GUI functionality, it provides
548 functionality for accessing some commonly-used operating system
549 facilities, such as copying or deleting files. wxWindows is a
550 'framework' in the sense that it provides a lot of built-in
551 functionality, which the application can use or replace as required,
552 thus saving a great deal of coding effort. Basic data structures such
553 as strings, linked lists and hash tables are also supported.
554
555 <p>
556 <h2>wxPython</h2>
557
558 wxPython is a Python extension module that encapsulates the wxWindows
559 GUI classes. Currently it is only available for the Win32 and GTK
560 ports of wxWindows, but as soon as the other ports are brought up to
561 the same level as Win32 and GTK, it should be fairly trivial to
562 enable wxPython to be used with the new GUI.
563
564 <p>
565
566 The wxPython extension module attempts to mirror the class heiarchy
567 of wxWindows as closely as possible. This means that there is a
568 wxFrame class in wxPython that looks, smells, tastes and acts almost
569 the same as the wxFrame class in the C++ version. Unfortunately,
570 because of differences in the languages, wxPython doesn't match
571 wxWindows exactly, but the differences should be easy to absorb
572 because they are natural to Python. For example, some methods that
573 return multiple values via argument pointers in C++ will return a
574 tuple of values in Python.
575
576 <p>
577
578 There is still much to be done for wxPython, many classes still need
579 to be mirrored. Also, wxWindows is still somewhat of a moving target
580 so it is a bit of an effort just keeping wxPython up to date. On the
581 other hand, there are enough of the core classes completed that
582 useful applications can be written.
583
584 <p>
585
586 wxPython is close enough to the C++ version that the majority of
587 the wxPython documentation is actually just notes attached to the C++
588 documents that describe the places where wxPython is different. There
589 is also a series of sample programs included, and a series of
590 documentation pages that assist the programmer in getting started
591 with wxPython.
592
593 """
cf694132
RD
594
595
596#----------------------------------------------------------------------------
597#----------------------------------------------------------------------------
598
599if __name__ == '__main__':
600 main()
601
602#----------------------------------------------------------------------------
603
604
605
606
607
608
609