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