]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/Main.py
fixed typo
[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',
f74ff5ef 25 'wxImageFromStream',
96de41c2 26 'RowColSizer',
03d84e7a 27 'Unicode',
7c41d11a 28 'wxFileHistory',
f6bcfd97 29 ]),
e395c057 30
6d19860f 31 ('Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame',
6d19860f
RD
32 'wxGrid', 'wxSashWindow',
33 'wxScrolledWindow', 'wxSplitterWindow',
34 'wxStatusBar', 'wxNotebook',
35 'wxHtmlWindow',
0122b7e3 36 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',
a57d56d6 37 'wxPopupWindow',
ebf4302c 38 'wxDynamicSashWindow',
0122b7e3 39 ]),
cf694132
RD
40
41 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
42 'wxSingleChoiceDialog', 'wxTextEntryDialog',
43 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
0122b7e3
RD
44 'wxMessageDialog', 'wxProgressDialog', 'wxFindReplaceDialog',
45 ]),
cf694132
RD
46
47 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
68320e40
RD
48 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'VirtualListCtrl',
49 'wxTextCtrl',
f6bcfd97
BP
50 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
51 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
d1679124 52 'wxCalendarCtrl', 'wxToggleButton',
950e7faf 53 'wxEditableListBox', 'wxLEDNumberCtrl',
6999b0d8 54 ]),
cf694132 55
96de41c2
RD
56 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource',
57 'RowColSizer',
58 ]),
cf694132 59
846ec2f9
RD
60 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'URLDragAndDrop',
61 'FontEnumerator',
b1462dfa 62 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
9b3d3bc4 63 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
f6bcfd97
BP
64 'PythonEvents', 'Threads',
65 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
493f1553 66 'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
b37c7e1d 67 'wxJoystick', 'DrawXXXList', 'ErrorDialogs', 'wxMimeTypesManager',
7c41d11a 68 'ContextHelp', 'SplitTree', 'Unicode', 'wxFileHistory',
f6bcfd97 69 ]),
cf694132 70
e0473f5f 71 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
f0261a72 72 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
c7e7022c 73 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
c368d904 74 'FileBrowseButton', 'GenericButtons', 'wxEditor',
c7e7022c 75 'ColourSelect', 'ImageBrowser',
68320e40
RD
76 'infoframe', 'ColourDB', 'PyCrust', 'PyCrustWithFilling',
77 'TablePrint',
729f4276 78 'wxRightTextCtrl',
c368d904 79 ]),
cf694132 80
611dc22c
RD
81 ('Cool Contribs', ['pyTree', 'hangman',
82 #'SlashDot',
83 'XMLtreeview'
84 ]),
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
6c5ae2d2
RD
103#---------------------------------------------------------------------------
104
105def opj(path):
106 """Convert paths to the platform-specific separator"""
107 return apply(os.path.join, tuple(string.split(path, '/')))
108
109
76bfdc78
RD
110#---------------------------------------------------------------------------
111
cf694132 112class wxPythonDemo(wxFrame):
e9159fe8 113 overviewText = "wxPython Overview"
c368d904 114
cf694132 115 def __init__(self, parent, id, title):
f6bcfd97
BP
116 wxFrame.__init__(self, parent, -1, title, size = (800, 600),
117 style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE)
2f90df85 118
694759cf 119 self.cwd = os.getcwd()
3ca6a5f0 120 self.curOverview = ""
694759cf 121
afb810d9 122 icon = images.getMondrianIcon()
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
ccf691a4 136 self.showTip = true
cf694132 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 |
afb810d9
RD
195 wxTR_HAS_VARIABLE_ROW_HEIGHT)
196
f6bcfd97 197 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
e9159fe8 198 root = self.tree.AddRoot("wxPython Overview")
f6bcfd97
BP
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))
e9159fe8 223 self.nb.AddPage(self.ovr, self.overviewText)
c368d904 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 227 self.ovr = wxHtmlWindow(panel, -1, size=(400, 400))
e9159fe8 228 self.nb.AddPage(panel, self.overviewText)
c368d904
RD
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 236
e9159fe8 237 self.SetOverview(self.overviewText, 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)
342639eb 249
f6bcfd97 250 # Set the wxWindows log target to be this textctrl
76bfdc78 251 #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
342639eb
RD
252
253 # But instead of the above we want to show how to use our own wxLog class
76bfdc78 254 wxLog_SetActiveTarget(MyLog(self.log))
cf694132
RD
255
256
5a7823f5 257
f6bcfd97 258 self.Show(true)
5a7823f5 259
f6bcfd97
BP
260 # add the windows to the splitter and split it.
261 splitter2.SplitHorizontally(self.nb, self.log)
f6bcfd97 262 splitter.SplitVertically(self.tree, splitter2)
afb810d9 263
f6bcfd97
BP
264 splitter.SetSashPosition(180, true)
265 splitter.SetMinimumPaneSize(20)
afb810d9
RD
266 splitter2.SetSashPosition(450, true)
267 splitter2.SetMinimumPaneSize(20)
268
cf694132 269
cf694132 270
bb0054cd
RD
271 # select initial items
272 self.nb.SetSelection(0)
f6bcfd97 273 self.tree.SelectItem(root)
ec3e670f
RD
274
275 if len(sys.argv) == 2:
276 try:
277 selectedDemo = self.treeMap[sys.argv[1]]
278 except:
279 selectedDemo = None
f6bcfd97 280 if selectedDemo:
ec3e670f
RD
281 self.tree.SelectItem(selectedDemo)
282 self.tree.EnsureVisible(selectedDemo)
283
bb0054cd 284
f6bcfd97 285 wxLogMessage('window handle: %s' % self.GetHandle())
2abc0a0f
RD
286
287
cf694132
RD
288 #---------------------------------------------
289 def WriteText(self, text):
f6bcfd97
BP
290 if text[-1:] == '\n':
291 text = text[:-1]
292 wxLogMessage(text)
293
cf694132
RD
294
295 def write(self, txt):
296 self.WriteText(txt)
297
298 #---------------------------------------------
299 def OnItemExpanded(self, event):
300 item = event.GetItem()
f6bcfd97 301 wxLogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
c368d904 302 event.Skip()
cf694132
RD
303
304 #---------------------------------------------
305 def OnItemCollapsed(self, event):
306 item = event.GetItem()
f6bcfd97 307 wxLogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
c368d904 308 event.Skip()
f6bcfd97
BP
309
310 #---------------------------------------------
311 def OnTreeLeftDown(self, event):
312 pt = event.GetPosition();
313 item, flags = self.tree.HitTest(pt)
314 if item == self.tree.GetSelection():
315 self.SetOverview(self.tree.GetItemText(item), self.curOverview)
185d7c3e 316 event.Skip()
cf694132
RD
317
318 #---------------------------------------------
319 def OnSelChanged(self, event):
320 if self.dying:
321 return
322
5a7823f5
RD
323 item = event.GetItem()
324 itemText = self.tree.GetItemText(item)
325 self.RunDemo(itemText)
326
327
328 #---------------------------------------------
329 def RunDemo(self, itemText):
694759cf 330 os.chdir(self.cwd)
cf694132
RD
331 if self.nb.GetPageCount() == 3:
332 if self.nb.GetSelection() == 2:
333 self.nb.SetSelection(0)
334 self.nb.DeletePage(2)
335
e9159fe8 336 if itemText == self.overviewText:
cf694132 337 self.GetDemoFile('Main.py')
e9159fe8 338 self.SetOverview(self.overviewText, overview)
cf694132 339 self.nb.Refresh();
e91a9dfc 340 self.window = None
cf694132
RD
341
342 else:
343 if os.path.exists(itemText + '.py'):
9d8bd15f 344 wxBeginBusyCursor()
f6bcfd97
BP
345 wxLogMessage("Running demo %s.py..." % itemText)
346 try:
347 self.GetDemoFile(itemText + '.py')
348 module = __import__(itemText, globals())
e9159fe8 349 self.SetOverview(itemText + " Overview", module.overview)
f6bcfd97
BP
350 finally:
351 wxEndBusyCursor()
cf694132
RD
352
353 # in case runTest is modal, make sure things look right...
354 self.nb.Refresh();
355 wxYield()
356
f6bcfd97 357 self.window = module.runTest(self, self.nb, self) ###
e91a9dfc
RD
358 if self.window:
359 self.nb.AddPage(self.window, 'Demo')
dcd38683 360 wxYield()
cf694132 361 self.nb.SetSelection(2)
cf694132
RD
362
363 else:
f6bcfd97 364 self.ovr.SetPage("")
cf694132 365 self.txt.Clear()
e91a9dfc 366 self.window = None
cf694132 367
2f90df85 368
cf694132
RD
369
370 #---------------------------------------------
371 # Get the Demo files
372 def GetDemoFile(self, filename):
373 self.txt.Clear()
bb0054cd
RD
374 try:
375 self.txt.SetValue(open(filename).read())
8bf5d46e 376 except IOError:
cf694132
RD
377 self.txt.WriteText("Cannot open %s file." % filename)
378
379 self.txt.SetInsertionPoint(0)
380 self.txt.ShowPosition(0)
381
382 #---------------------------------------------
383 def SetOverview(self, name, text):
f6bcfd97
BP
384 self.curOverview = text
385 lead = text[:6]
386 if lead != '<html>' and lead != '<HTML>':
387 text = string.join(string.split(text, '\n'), '<br>')
f6bcfd97 388 self.ovr.SetPage(text)
cf694132 389 self.nb.SetPageText(0, name)
cf694132
RD
390
391 #---------------------------------------------
392 # Menu methods
c368d904 393 def OnFileExit(self, *event):
cf694132
RD
394 self.Close()
395
396
397 def OnHelpAbout(self, event):
e166644c 398 from About import MyAboutBox
ec3e670f 399 about = MyAboutBox(self)
cf694132
RD
400 about.ShowModal()
401 about.Destroy()
402
403
404 #---------------------------------------------
405 def OnCloseWindow(self, event):
406 self.dying = true
e91a9dfc 407 self.window = None
26197023 408 self.mainmenu = None
c368d904
RD
409 if hasattr(self, "tbicon"):
410 del self.tbicon
cf694132
RD
411 self.Destroy()
412
c368d904 413
cf694132
RD
414 #---------------------------------------------
415 def OnIdle(self, event):
416 if self.otherWin:
417 self.otherWin.Raise()
e91a9dfc 418 self.window = self.otherWin
cf694132
RD
419 self.otherWin = None
420
ccf691a4
RD
421 if self.showTip:
422 self.ShowTip()
423 self.showTip = false
424
425
426 #---------------------------------------------
427 def ShowTip(self):
428 try:
429 showTipText = open(opj("data/showTips")).read()
430 showTip, index = eval(showTipText)
431 except IOError:
432 showTip, index = (1, 0)
433 if showTip:
434 tp = wxCreateFileTipProvider(opj("data/tips.txt"), index)
435 showTip = wxShowTip(self, tp)
436 index = tp.GetCurrentTip()
437 open(opj("data/showTips"), "w").write(str( (showTip, index) ))
438
439
ec3e670f
RD
440 #---------------------------------------------
441 def OnDemoMenu(self, event):
f6bcfd97
BP
442 try:
443 selectedDemo = self.treeMap[self.mainmenu.GetLabel(event.GetId())]
444 except:
445 selectedDemo = None
446 if selectedDemo:
447 self.tree.SelectItem(selectedDemo)
448 self.tree.EnsureVisible(selectedDemo)
ec3e670f 449
c368d904
RD
450
451 #---------------------------------------------
452 def OnTaskBarActivate(self, evt):
453 if self.IsIconized():
454 self.Iconize(false)
455 if not self.IsShown():
456 self.Show(true)
457 self.Raise()
458
459 #---------------------------------------------
460
461 TBMENU_RESTORE = 1000
462 TBMENU_CLOSE = 1001
463
464 def OnTaskBarMenu(self, evt):
465 menu = wxMenu()
466 menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
467 menu.Append(self.TBMENU_CLOSE, "Close")
468 self.tbicon.PopupMenu(menu)
469 menu.Destroy()
470
471 #---------------------------------------------
472 def OnTaskBarClose(self, evt):
473 self.Close()
474
475 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
476 # prod the main idle handler a bit to get the window to actually close
477 wxGetApp().ProcessIdle()
478
479
f3d9dc1d
RD
480 #---------------------------------------------
481 def OnIconfiy(self, evt):
482 wxLogMessage("OnIconfiy")
483 evt.Skip()
484
485 #---------------------------------------------
486 def OnMaximize(self, evt):
487 wxLogMessage("OnMaximize")
488 evt.Skip()
489
490
491
492
cf694132
RD
493#---------------------------------------------------------------------------
494#---------------------------------------------------------------------------
495
b5a5d647
RD
496class MySplashScreen(wxSplashScreen):
497 def __init__(self):
6c5ae2d2 498 bmp = wxImage(opj("bitmaps/splash.gif")).ConvertToBitmap()
b5a5d647
RD
499 wxSplashScreen.__init__(self, bmp,
500 wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT,
501 4000, None, -1)
502 EVT_CLOSE(self, self.OnClose)
503
504 def OnClose(self, evt):
9fb56e0c 505 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
cf694132 506 frame.Show(true)
ccf691a4 507 evt.Skip() # Make sure the default handler runs too...
cf694132 508
b5a5d647
RD
509
510class MyApp(wxApp):
511 def OnInit(self):
512 """
68320e40 513 Create and show the splash screen. It will then create and show
b5a5d647
RD
514 the main frame when it is time to do so.
515 """
516 wxInitAllImageHandlers()
517 splash = MySplashScreen()
518 splash.Show()
b5a5d647
RD
519 return true
520
521
522
cf694132
RD
523#---------------------------------------------------------------------------
524
525def main():
e02c03a4 526 try:
d56cebe7 527 demoPath = os.path.dirname(__file__)
e02c03a4
RD
528 os.chdir(demoPath)
529 except:
530 pass
cf694132
RD
531 app = MyApp(0)
532 app.MainLoop()
533
534
535#---------------------------------------------------------------------------
536
537
538
f6bcfd97
BP
539overview = """<html><body>
540 <h2>Python</h2>
541
542 Python is an interpreted, interactive, object-oriented programming
543 language often compared to Tcl, Perl, Scheme, or Java.
544
545 <p> Python combines remarkable power with very clear syntax. It has
546 modules, classes, exceptions, very high level dynamic data types, and
547 dynamic typing. There are interfaces to many system calls and
548 libraries, and new built-in modules are easily written in C or
549 C++. Python is also usable as an extension language for applications
550 that need a programmable interface. <p>
551
552 <h2>wxWindows</h2>
553
554 wxWindows is a free C++ framework designed to make cross-platform
555 programming child's play. Well, almost. wxWindows 2 supports Windows
556 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
557 underway. Other ports are under consideration. <p>
558
559 wxWindows is a set of libraries that allows C++ applications to
560 compile and run on several different types of computers, with minimal
561 source code changes. There is one library per supported GUI (such as
562 Motif, or Windows). As well as providing a common API (Application
563 Programming Interface) for GUI functionality, it provides
564 functionality for accessing some commonly-used operating system
565 facilities, such as copying or deleting files. wxWindows is a
566 'framework' in the sense that it provides a lot of built-in
567 functionality, which the application can use or replace as required,
568 thus saving a great deal of coding effort. Basic data structures such
569 as strings, linked lists and hash tables are also supported.
570
571 <p>
572 <h2>wxPython</h2>
573
574 wxPython is a Python extension module that encapsulates the wxWindows
575 GUI classes. Currently it is only available for the Win32 and GTK
576 ports of wxWindows, but as soon as the other ports are brought up to
577 the same level as Win32 and GTK, it should be fairly trivial to
578 enable wxPython to be used with the new GUI.
579
580 <p>
581
582 The wxPython extension module attempts to mirror the class heiarchy
583 of wxWindows as closely as possible. This means that there is a
584 wxFrame class in wxPython that looks, smells, tastes and acts almost
585 the same as the wxFrame class in the C++ version. Unfortunately,
586 because of differences in the languages, wxPython doesn't match
587 wxWindows exactly, but the differences should be easy to absorb
588 because they are natural to Python. For example, some methods that
589 return multiple values via argument pointers in C++ will return a
590 tuple of values in Python.
591
592 <p>
593
594 There is still much to be done for wxPython, many classes still need
595 to be mirrored. Also, wxWindows is still somewhat of a moving target
596 so it is a bit of an effort just keeping wxPython up to date. On the
597 other hand, there are enough of the core classes completed that
598 useful applications can be written.
599
600 <p>
601
602 wxPython is close enough to the C++ version that the majority of
603 the wxPython documentation is actually just notes attached to the C++
604 documents that describe the places where wxPython is different. There
605 is also a series of sample programs included, and a series of
606 documentation pages that assist the programmer in getting started
607 with wxPython.
608
609 """
cf694132
RD
610
611
612#----------------------------------------------------------------------------
613#----------------------------------------------------------------------------
614
615if __name__ == '__main__':
616 main()
617
618#----------------------------------------------------------------------------
619
620
621
622
623
624
625