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