]> git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/Main.py
use specific linker flags under Mac OS X when linking executables against the
[wxWidgets.git] / wxPython / demo / Main.py
1 #!/bin/env python
2 #----------------------------------------------------------------------------
3 # Name: Main.py
4 # Purpose: Testing lots of stuff, controls, window types, etc.
5 #
6 # Author: Robin Dunn
7 #
8 # Created: A long time ago, in a galaxy far, far away...
9 # RCS-ID: $Id$
10 # Copyright: (c) 1999 by Total Control Software
11 # Licence: wxWindows license
12 #----------------------------------------------------------------------------
13
14 import sys, os, time, string
15 from wxPython.wx import *
16 from wxPython.html import wxHtmlWindow
17
18 import images
19
20 #---------------------------------------------------------------------------
21
22
23 ## _treeList = [
24 ## ('New since last release', ['wxGenericDirCtrl',
25 ## 'wxImageFromStream',
26 ## 'RowColSizer',
27 ## 'Unicode',
28 ## 'wxFileHistory',
29 ## ]),
30
31 ## ('Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame',
32 ## 'wxGrid', 'wxSashWindow',
33 ## 'wxScrolledWindow', 'wxSplitterWindow',
34 ## 'wxStatusBar', 'wxNotebook',
35 ## 'wxHtmlWindow',
36 ## 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',
37 ## 'wxPopupWindow',
38 ## 'wxDynamicSashWindow',
39 ## ]),
40
41 ## ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
42 ## 'wxSingleChoiceDialog', 'wxTextEntryDialog',
43 ## 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
44 ## 'wxMessageDialog', 'wxProgressDialog', 'wxFindReplaceDialog',
45 ## ]),
46
47 ## ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
48 ## 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'VirtualListCtrl',
49 ## 'wxTextCtrl',
50 ## 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
51 ## 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
52 ## 'wxCalendarCtrl', 'wxToggleButton',
53 ## 'wxEditableListBox', 'wxLEDNumberCtrl',
54 ## ]),
55
56 ## ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource',
57 ## 'RowColSizer',
58 ## ]),
59
60 ## ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'URLDragAndDrop',
61 ## 'FontEnumerator',
62 ## 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
63 ## 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
64 ## 'PythonEvents', 'Threads',
65 ## 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
66 ## 'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
67 ## 'wxJoystick', 'DrawXXXList', 'ErrorDialogs', 'wxMimeTypesManager',
68 ## 'ContextHelp', 'SplitTree', 'Unicode', 'wxFileHistory',
69 ## ]),
70
71 ## ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
72 ## 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
73 ## 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
74 ## 'FileBrowseButton', 'GenericButtons', 'wxEditor',
75 ## 'ColourSelect', 'ImageBrowser',
76 ## 'infoframe', 'ColourDB', 'PyCrust', 'PyCrustWithFilling',
77 ## 'TablePrint',
78 ## 'wxRightTextCtrl',
79 ## ]),
80
81 ## ('Cool Contribs', ['pyTree', 'hangman',
82 ## #'SlashDot',
83 ## 'XMLtreeview'
84 ## ]),
85
86 ## ]
87
88
89 _treeList = [
90 # new stuff
91 ('New since last release', [
92 'RowColSizer',
93 'Unicode',
94 'wxFileHistory',
95 'wxGenericDirCtrl',
96 'wxImageFromStream',
97 ]),
98
99 # managed windows == things with a caption you can close
100 ('Base Frames and Dialogs', [
101 'wxDialog',
102 'wxFrame',
103 'wxMDIWindows',
104 'wxMiniFrame',
105 ]),
106
107 # the common dialogs
108 ('Common Dialogs', [
109 'wxColourDialog',
110 'wxDirDialog',
111 'wxFileDialog',
112 'wxFindReplaceDialog',
113 'wxFontDialog',
114 'wxMessageDialog',
115 'wxPageSetupDialog',
116 'wxPrintDialog',
117 'wxProgressDialog',
118 'wxSingleChoiceDialog',
119 'wxTextEntryDialog',
120 ]),
121
122 # dialogs form libraries
123 ('More Dialogs', [
124 'ErrorDialogs',
125 'ImageBrowser',
126 'wxMultipleChoiceDialog',
127 'wxScrolledMessageDialog',
128 ]),
129
130 # core controls
131 ('Core Windows/Controls', [
132 'VirtualListCtrl',
133 'wxButton',
134 'wxCheckBox',
135 'wxCheckListBox',
136 'wxChoice',
137 'wxComboBox',
138 'wxGauge',
139 'wxGenericDirCtrl',
140 'wxGrid',
141 'wxListBox',
142 'wxListCtrl',
143 'wxNotebook',
144 'wxPopupWindow',
145 'wxRadioBox',
146 'wxSashWindow',
147 'wxSlider',
148 'wxScrolledWindow',
149 'wxSplitterWindow',
150 'wxSpinButton',
151 'wxSpinCtrl',
152 'wxStaticText',
153 'wxStaticBitmap',
154 'wxStatusBar',
155 'wxTextCtrl',
156 'wxTimer',
157 'wxToggleButton',
158 'wxToolBar',
159 'wxTreeCtrl',
160 'wxValidator',
161 ]),
162
163 # controls coming from other librairies
164 ('More Windows/Controls', [
165 'ColourSelect',
166 'ContextHelp',
167 'FancyText',
168 'FileBrowseButton',
169 'GenericButtons',
170 'PyCrust',
171 'PyCrustWithFilling',
172 'SplitTree',
173 'TablePrint',
174 'wxCalendar',
175 'wxCalendarCtrl',
176 'wxDynamicSashWindow',
177 'wxEditableListBox',
178 'wxEditor',
179 'wxFloatBar',
180 'wxHtmlWindow',
181 'wxLEDNumberCtrl',
182 'wxMimeTypesManager',
183 'wxMVCTree',
184 'wxStyledTextCtrl_1',
185 'wxStyledTextCtrl_2',
186 'wxRightTextCtrl',
187 ]),
188
189 # How to lay out the controls in a frame/dialog
190 ('Window Layout', [
191 'LayoutAnchors',
192 'Layoutf',
193 'RowColSizer',
194 'Sizers',
195 'wxLayoutConstraints',
196 'XML_Resource',
197 ]),
198
199 # ditto
200 ('Process and Events', [
201 'infoframe',
202 'OOR',
203 'PythonEvents',
204 'Threads',
205 'wxProcess',
206 'wxTimer',
207 ]),
208
209 # Clipboard and DnD
210 ('Clipboard and DnD', [
211 'CustomDragAndDrop',
212 'DragAndDrop',
213 'URLDragAndDrop',
214 ]),
215
216 # Images
217 ('Images', [
218 'wxDragImage',
219 'wxImage',
220 'wxImageFromStream',
221 'wxMask',
222 ]),
223
224 # Other stuff
225 ('Miscellaneous', [
226 'ColourDB',
227 'DialogUnits',
228 'DrawXXXList',
229 'FontEnumerator',
230 'PrintFramework',
231 'Unicode',
232 'wxFileHistory',
233 'wxJoystick',
234 'wxOGL',
235 'wxWave',
236 ]),
237
238 # need libs not coming with the demo
239 ('Objects using an external library', [
240 'ActiveXWrapper_Acrobat',
241 'ActiveXWrapper_IE',
242 'wxGLCanvas',
243 'wxPlotCanvas',
244 'wxVTKRenderWindow',
245 ]),
246
247 # pyTree, hangman, ... in the samples dir
248 ('Check out the samples dir too', [
249 ]),
250
251 #~ ('Cool Contribs', [
252 #~ 'pyTree',
253 #~ 'hangman',
254 #'SlashDot',
255 #~ 'XMLtreeview'
256 #~ ]),
257 ]
258
259
260
261 #---------------------------------------------------------------------------
262
263 class MyLog(wxPyLog):
264 def __init__(self, textCtrl, logTime=0):
265 wxPyLog.__init__(self)
266 self.tc = textCtrl
267 self.logTime = logTime
268
269 def DoLogString(self, message, timeStamp):
270 if self.logTime:
271 message = time.strftime("%X", time.localtime(timeStamp)) + \
272 ": " + message
273 self.tc.AppendText(message + '\n')
274
275
276 #---------------------------------------------------------------------------
277
278 def opj(path):
279 """Convert paths to the platform-specific separator"""
280 return apply(os.path.join, tuple(string.split(path, '/')))
281
282
283 #---------------------------------------------------------------------------
284
285 class wxPythonDemo(wxFrame):
286 overviewText = "wxPython Overview"
287
288 def __init__(self, parent, id, title):
289 wxFrame.__init__(self, parent, -1, title, size = (800, 600),
290 style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE)
291
292 self.cwd = os.getcwd()
293 self.curOverview = ""
294
295 icon = images.getMondrianIcon()
296 self.SetIcon(icon)
297
298 if wxPlatform == '__WXMSW__':
299 # setup a taskbar icon, and catch some events from it
300 self.tbicon = wxTaskBarIcon()
301 self.tbicon.SetIcon(icon, "wxPython Demo")
302 EVT_TASKBAR_LEFT_DCLICK(self.tbicon, self.OnTaskBarActivate)
303 EVT_TASKBAR_RIGHT_UP(self.tbicon, self.OnTaskBarMenu)
304 EVT_MENU(self.tbicon, self.TBMENU_RESTORE, self.OnTaskBarActivate)
305 EVT_MENU(self.tbicon, self.TBMENU_CLOSE, self.OnTaskBarClose)
306
307
308 self.otherWin = None
309 self.showTip = true
310 EVT_IDLE(self, self.OnIdle)
311 EVT_CLOSE(self, self.OnCloseWindow)
312 EVT_ICONIZE(self, self.OnIconfiy)
313 EVT_MAXIMIZE(self, self.OnMaximize)
314
315 self.Centre(wxBOTH)
316 self.CreateStatusBar(1, wxST_SIZEGRIP)
317
318 splitter = wxSplitterWindow(self, -1, style=wxNO_3D|wxSP_3D)
319 splitter2 = wxSplitterWindow(splitter, -1, style=wxNO_3D|wxSP_3D)
320
321 def EmptyHandler(evt): pass
322 EVT_ERASE_BACKGROUND(splitter, EmptyHandler)
323 EVT_ERASE_BACKGROUND(splitter2, EmptyHandler)
324
325 # Prevent TreeCtrl from displaying all items after destruction when true
326 self.dying = false
327
328 # Make a File menu
329 self.mainmenu = wxMenuBar()
330 menu = wxMenu()
331 exitID = wxNewId()
332 menu.Append(exitID, 'E&xit\tAlt-X', 'Get the heck outta here!')
333 EVT_MENU(self, exitID, self.OnFileExit)
334 self.mainmenu.Append(menu, '&File')
335
336 # Make a Demo menu
337 menu = wxMenu()
338 for item in _treeList:
339 submenu = wxMenu()
340 for childItem in item[1]:
341 mID = wxNewId()
342 submenu.Append(mID, childItem)
343 EVT_MENU(self, mID, self.OnDemoMenu)
344 menu.AppendMenu(wxNewId(), item[0], submenu)
345 self.mainmenu.Append(menu, '&Demo')
346
347
348 # Make a Help menu
349 helpID = wxNewId()
350 menu = wxMenu()
351 menu.Append(helpID, '&About\tCtrl-H', 'wxPython RULES!!!')
352 EVT_MENU(self, helpID, self.OnHelpAbout)
353 self.mainmenu.Append(menu, '&Help')
354 self.SetMenuBar(self.mainmenu)
355
356 # set the menu accellerator table...
357 aTable = wxAcceleratorTable([(wxACCEL_ALT, ord('X'), exitID),
358 (wxACCEL_CTRL, ord('H'), helpID)])
359 self.SetAcceleratorTable(aTable)
360
361
362 # Create a TreeCtrl
363 tID = wxNewId()
364 self.treeMap = {}
365 self.tree = wxTreeCtrl(splitter, tID,
366 style=wxTR_HAS_BUTTONS |
367 wxTR_EDIT_LABELS |
368 wxTR_HAS_VARIABLE_ROW_HEIGHT)
369
370 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
371 root = self.tree.AddRoot("wxPython Overview")
372 firstChild = None
373 for item in _treeList:
374 child = self.tree.AppendItem(root, item[0])
375 if not firstChild: firstChild = child
376 for childItem in item[1]:
377 theDemo = self.tree.AppendItem(child, childItem)
378 self.treeMap[childItem] = theDemo
379
380 self.tree.Expand(root)
381 self.tree.Expand(firstChild)
382 EVT_TREE_ITEM_EXPANDED (self.tree, tID, self.OnItemExpanded)
383 EVT_TREE_ITEM_COLLAPSED (self.tree, tID, self.OnItemCollapsed)
384 EVT_TREE_SEL_CHANGED (self.tree, tID, self.OnSelChanged)
385 EVT_LEFT_DOWN (self.tree, self.OnTreeLeftDown)
386
387 # Create a Notebook
388 self.nb = wxNotebook(splitter2, -1, style=wxCLIP_CHILDREN)
389
390 # Set up a wxHtmlWindow on the Overview Notebook page
391 # we put it in a panel first because there seems to be a
392 # refresh bug of some sort (wxGTK) when it is directly in
393 # the notebook...
394 if 0: # the old way
395 self.ovr = wxHtmlWindow(self.nb, -1, size=(400, 400))
396 self.nb.AddPage(self.ovr, self.overviewText)
397
398 else: # hopefully I can remove this hacky code soon, see bug #216861
399 panel = wxPanel(self.nb, -1, style=wxCLIP_CHILDREN)
400 self.ovr = wxHtmlWindow(panel, -1, size=(400, 400))
401 self.nb.AddPage(panel, self.overviewText)
402
403 def OnOvrSize(evt, ovr=self.ovr):
404 ovr.SetSize(evt.GetSize())
405
406 EVT_SIZE(panel, OnOvrSize)
407 EVT_ERASE_BACKGROUND(panel, EmptyHandler)
408
409
410 self.SetOverview(self.overviewText, overview)
411
412
413 # Set up a TextCtrl on the Demo Code Notebook page
414 self.txt = wxTextCtrl(self.nb, -1,
415 style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
416 self.nb.AddPage(self.txt, "Demo Code")
417
418
419 # Set up a log on the View Log Notebook page
420 self.log = wxTextCtrl(splitter2, -1,
421 style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
422
423 # Set the wxWindows log target to be this textctrl
424 #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
425
426 # But instead of the above we want to show how to use our own wxLog class
427 wxLog_SetActiveTarget(MyLog(self.log))
428
429
430
431 self.Show(true)
432
433 # add the windows to the splitter and split it.
434 splitter2.SplitHorizontally(self.nb, self.log)
435 splitter.SplitVertically(self.tree, splitter2)
436
437 splitter.SetSashPosition(180, true)
438 splitter.SetMinimumPaneSize(20)
439 splitter2.SetSashPosition(450, true)
440 splitter2.SetMinimumPaneSize(20)
441
442
443
444 # select initial items
445 self.nb.SetSelection(0)
446 self.tree.SelectItem(root)
447
448 if len(sys.argv) == 2:
449 try:
450 selectedDemo = self.treeMap[sys.argv[1]]
451 except:
452 selectedDemo = None
453 if selectedDemo:
454 self.tree.SelectItem(selectedDemo)
455 self.tree.EnsureVisible(selectedDemo)
456
457
458 wxLogMessage('window handle: %s' % self.GetHandle())
459
460
461 #---------------------------------------------
462 def WriteText(self, text):
463 if text[-1:] == '\n':
464 text = text[:-1]
465 wxLogMessage(text)
466
467
468 def write(self, txt):
469 self.WriteText(txt)
470
471 #---------------------------------------------
472 def OnItemExpanded(self, event):
473 item = event.GetItem()
474 wxLogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
475 event.Skip()
476
477 #---------------------------------------------
478 def OnItemCollapsed(self, event):
479 item = event.GetItem()
480 wxLogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
481 event.Skip()
482
483 #---------------------------------------------
484 def OnTreeLeftDown(self, event):
485 pt = event.GetPosition();
486 item, flags = self.tree.HitTest(pt)
487 if item == self.tree.GetSelection():
488 self.SetOverview(self.tree.GetItemText(item), self.curOverview)
489 event.Skip()
490
491 #---------------------------------------------
492 def OnSelChanged(self, event):
493 if self.dying:
494 return
495
496 item = event.GetItem()
497 itemText = self.tree.GetItemText(item)
498 self.RunDemo(itemText)
499
500
501 #---------------------------------------------
502 def RunDemo(self, itemText):
503 os.chdir(self.cwd)
504 if self.nb.GetPageCount() == 3:
505 if self.nb.GetSelection() == 2:
506 self.nb.SetSelection(0)
507 self.nb.DeletePage(2)
508
509 if itemText == self.overviewText:
510 self.GetDemoFile('Main.py')
511 self.SetOverview(self.overviewText, overview)
512 self.nb.Refresh();
513 self.window = None
514
515 else:
516 if os.path.exists(itemText + '.py'):
517 wxBeginBusyCursor()
518 wxLogMessage("Running demo %s.py..." % itemText)
519 try:
520 self.GetDemoFile(itemText + '.py')
521 module = __import__(itemText, globals())
522 self.SetOverview(itemText + " Overview", module.overview)
523 finally:
524 wxEndBusyCursor()
525
526 # in case runTest is modal, make sure things look right...
527 self.nb.Refresh();
528 wxYield()
529
530 self.window = module.runTest(self, self.nb, self) ###
531 if self.window:
532 self.nb.AddPage(self.window, 'Demo')
533 wxYield()
534 self.nb.SetSelection(2)
535
536 else:
537 self.ovr.SetPage("")
538 self.txt.Clear()
539 self.window = None
540
541
542
543 #---------------------------------------------
544 # Get the Demo files
545 def GetDemoFile(self, filename):
546 self.txt.Clear()
547 try:
548 self.txt.SetValue(open(filename).read())
549 except IOError:
550 self.txt.WriteText("Cannot open %s file." % filename)
551
552 self.txt.SetInsertionPoint(0)
553 self.txt.ShowPosition(0)
554
555 #---------------------------------------------
556 def SetOverview(self, name, text):
557 self.curOverview = text
558 lead = text[:6]
559 if lead != '<html>' and lead != '<HTML>':
560 text = string.join(string.split(text, '\n'), '<br>')
561 self.ovr.SetPage(text)
562 self.nb.SetPageText(0, name)
563
564 #---------------------------------------------
565 # Menu methods
566 def OnFileExit(self, *event):
567 self.Close()
568
569
570 def OnHelpAbout(self, event):
571 from About import MyAboutBox
572 about = MyAboutBox(self)
573 about.ShowModal()
574 about.Destroy()
575
576
577 #---------------------------------------------
578 def OnCloseWindow(self, event):
579 self.dying = true
580 self.window = None
581 self.mainmenu = None
582 if hasattr(self, "tbicon"):
583 del self.tbicon
584 self.Destroy()
585
586
587 #---------------------------------------------
588 def OnIdle(self, event):
589 if self.otherWin:
590 self.otherWin.Raise()
591 self.window = self.otherWin
592 self.otherWin = None
593
594 if self.showTip:
595 self.ShowTip()
596 self.showTip = false
597
598
599 #---------------------------------------------
600 def ShowTip(self):
601 try:
602 showTipText = open(opj("data/showTips")).read()
603 showTip, index = eval(showTipText)
604 except IOError:
605 showTip, index = (1, 0)
606 if showTip:
607 tp = wxCreateFileTipProvider(opj("data/tips.txt"), index)
608 showTip = wxShowTip(self, tp)
609 index = tp.GetCurrentTip()
610 open(opj("data/showTips"), "w").write(str( (showTip, index) ))
611
612
613 #---------------------------------------------
614 def OnDemoMenu(self, event):
615 try:
616 selectedDemo = self.treeMap[self.mainmenu.GetLabel(event.GetId())]
617 except:
618 selectedDemo = None
619 if selectedDemo:
620 self.tree.SelectItem(selectedDemo)
621 self.tree.EnsureVisible(selectedDemo)
622
623
624 #---------------------------------------------
625 def OnTaskBarActivate(self, evt):
626 if self.IsIconized():
627 self.Iconize(false)
628 if not self.IsShown():
629 self.Show(true)
630 self.Raise()
631
632 #---------------------------------------------
633
634 TBMENU_RESTORE = 1000
635 TBMENU_CLOSE = 1001
636
637 def OnTaskBarMenu(self, evt):
638 menu = wxMenu()
639 menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
640 menu.Append(self.TBMENU_CLOSE, "Close")
641 self.tbicon.PopupMenu(menu)
642 menu.Destroy()
643
644 #---------------------------------------------
645 def OnTaskBarClose(self, evt):
646 self.Close()
647
648 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
649 # prod the main idle handler a bit to get the window to actually close
650 wxGetApp().ProcessIdle()
651
652
653 #---------------------------------------------
654 def OnIconfiy(self, evt):
655 wxLogMessage("OnIconfiy")
656 evt.Skip()
657
658 #---------------------------------------------
659 def OnMaximize(self, evt):
660 wxLogMessage("OnMaximize")
661 evt.Skip()
662
663
664
665
666 #---------------------------------------------------------------------------
667 #---------------------------------------------------------------------------
668
669 class MySplashScreen(wxSplashScreen):
670 def __init__(self):
671 bmp = wxImage(opj("bitmaps/splash.gif")).ConvertToBitmap()
672 wxSplashScreen.__init__(self, bmp,
673 wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT,
674 4000, None, -1)
675 EVT_CLOSE(self, self.OnClose)
676
677 def OnClose(self, evt):
678 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
679 frame.Show(true)
680 evt.Skip() # Make sure the default handler runs too...
681
682
683 class MyApp(wxApp):
684 def OnInit(self):
685 """
686 Create and show the splash screen. It will then create and show
687 the main frame when it is time to do so.
688 """
689 wxInitAllImageHandlers()
690 splash = MySplashScreen()
691 splash.Show()
692 return true
693
694
695
696 #---------------------------------------------------------------------------
697
698 def main():
699 try:
700 demoPath = os.path.dirname(__file__)
701 os.chdir(demoPath)
702 except:
703 pass
704 app = MyApp(0)
705 app.MainLoop()
706
707
708 #---------------------------------------------------------------------------
709
710
711
712 overview = """<html><body>
713 <h2>Python</h2>
714
715 Python is an interpreted, interactive, object-oriented programming
716 language often compared to Tcl, Perl, Scheme, or Java.
717
718 <p> Python combines remarkable power with very clear syntax. It has
719 modules, classes, exceptions, very high level dynamic data types, and
720 dynamic typing. There are interfaces to many system calls and
721 libraries, and new built-in modules are easily written in C or
722 C++. Python is also usable as an extension language for applications
723 that need a programmable interface. <p>
724
725 <h2>wxWindows</h2>
726
727 wxWindows is a free C++ framework designed to make cross-platform
728 programming child's play. Well, almost. wxWindows 2 supports Windows
729 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
730 underway. Other ports are under consideration. <p>
731
732 wxWindows is a set of libraries that allows C++ applications to
733 compile and run on several different types of computers, with minimal
734 source code changes. There is one library per supported GUI (such as
735 Motif, or Windows). As well as providing a common API (Application
736 Programming Interface) for GUI functionality, it provides
737 functionality for accessing some commonly-used operating system
738 facilities, such as copying or deleting files. wxWindows is a
739 'framework' in the sense that it provides a lot of built-in
740 functionality, which the application can use or replace as required,
741 thus saving a great deal of coding effort. Basic data structures such
742 as strings, linked lists and hash tables are also supported.
743
744 <p>
745 <h2>wxPython</h2>
746
747 wxPython is a Python extension module that encapsulates the wxWindows
748 GUI classes. Currently it is only available for the Win32 and GTK
749 ports of wxWindows, but as soon as the other ports are brought up to
750 the same level as Win32 and GTK, it should be fairly trivial to
751 enable wxPython to be used with the new GUI.
752
753 <p>
754
755 The wxPython extension module attempts to mirror the class heiarchy
756 of wxWindows as closely as possible. This means that there is a
757 wxFrame class in wxPython that looks, smells, tastes and acts almost
758 the same as the wxFrame class in the C++ version. Unfortunately,
759 because of differences in the languages, wxPython doesn't match
760 wxWindows exactly, but the differences should be easy to absorb
761 because they are natural to Python. For example, some methods that
762 return multiple values via argument pointers in C++ will return a
763 tuple of values in Python.
764
765 <p>
766
767 There is still much to be done for wxPython, many classes still need
768 to be mirrored. Also, wxWindows is still somewhat of a moving target
769 so it is a bit of an effort just keeping wxPython up to date. On the
770 other hand, there are enough of the core classes completed that
771 useful applications can be written.
772
773 <p>
774
775 wxPython is close enough to the C++ version that the majority of
776 the wxPython documentation is actually just notes attached to the C++
777 documents that describe the places where wxPython is different. There
778 is also a series of sample programs included, and a series of
779 documentation pages that assist the programmer in getting started
780 with wxPython.
781
782 """
783
784
785 #----------------------------------------------------------------------------
786 #----------------------------------------------------------------------------
787
788 if __name__ == '__main__':
789 main()
790
791 #----------------------------------------------------------------------------
792
793
794
795
796
797
798