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