]> git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/Main.py
89372d40b9120d9ef6ef04a5c4fe88074d5b62a2
[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 ]
252
253
254
255 #---------------------------------------------------------------------------
256
257 class MyLog(wxPyLog):
258 def __init__(self, textCtrl, logTime=0):
259 wxPyLog.__init__(self)
260 self.tc = textCtrl
261 self.logTime = logTime
262
263 def DoLogString(self, message, timeStamp):
264 if self.logTime:
265 message = time.strftime("%X", time.localtime(timeStamp)) + \
266 ": " + message
267 self.tc.AppendText(message + '\n')
268
269
270 #---------------------------------------------------------------------------
271
272 def opj(path):
273 """Convert paths to the platform-specific separator"""
274 return apply(os.path.join, tuple(string.split(path, '/')))
275
276
277 #---------------------------------------------------------------------------
278
279 class wxPythonDemo(wxFrame):
280 overviewText = "wxPython Overview"
281
282 def __init__(self, parent, id, title):
283 wxFrame.__init__(self, parent, -1, title, size = (800, 600),
284 style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE)
285
286 self.cwd = os.getcwd()
287 self.curOverview = ""
288
289 icon = images.getMondrianIcon()
290 self.SetIcon(icon)
291
292 if wxPlatform == '__WXMSW__':
293 # setup a taskbar icon, and catch some events from it
294 self.tbicon = wxTaskBarIcon()
295 self.tbicon.SetIcon(icon, "wxPython Demo")
296 EVT_TASKBAR_LEFT_DCLICK(self.tbicon, self.OnTaskBarActivate)
297 EVT_TASKBAR_RIGHT_UP(self.tbicon, self.OnTaskBarMenu)
298 EVT_MENU(self.tbicon, self.TBMENU_RESTORE, self.OnTaskBarActivate)
299 EVT_MENU(self.tbicon, self.TBMENU_CLOSE, self.OnTaskBarClose)
300
301
302 self.otherWin = None
303 self.showTip = true
304 EVT_IDLE(self, self.OnIdle)
305 EVT_CLOSE(self, self.OnCloseWindow)
306 EVT_ICONIZE(self, self.OnIconfiy)
307 EVT_MAXIMIZE(self, self.OnMaximize)
308
309 self.Centre(wxBOTH)
310 self.CreateStatusBar(1, wxST_SIZEGRIP)
311
312 splitter = wxSplitterWindow(self, -1, style=wxNO_3D|wxSP_3D)
313 splitter2 = wxSplitterWindow(splitter, -1, style=wxNO_3D|wxSP_3D)
314
315 def EmptyHandler(evt): pass
316 EVT_ERASE_BACKGROUND(splitter, EmptyHandler)
317 EVT_ERASE_BACKGROUND(splitter2, EmptyHandler)
318
319 # Prevent TreeCtrl from displaying all items after destruction when true
320 self.dying = false
321
322 # Make a File menu
323 self.mainmenu = wxMenuBar()
324 menu = wxMenu()
325 exitID = wxNewId()
326 menu.Append(exitID, 'E&xit\tAlt-X', 'Get the heck outta here!')
327 EVT_MENU(self, exitID, self.OnFileExit)
328 self.mainmenu.Append(menu, '&File')
329
330 # Make a Demo menu
331 menu = wxMenu()
332 for item in _treeList:
333 submenu = wxMenu()
334 for childItem in item[1]:
335 mID = wxNewId()
336 submenu.Append(mID, childItem)
337 EVT_MENU(self, mID, self.OnDemoMenu)
338 menu.AppendMenu(wxNewId(), item[0], submenu)
339 self.mainmenu.Append(menu, '&Demo')
340
341
342 # Make a Help menu
343 helpID = wxNewId()
344 menu = wxMenu()
345 menu.Append(helpID, '&About\tCtrl-H', 'wxPython RULES!!!')
346 EVT_MENU(self, helpID, self.OnHelpAbout)
347 self.mainmenu.Append(menu, '&Help')
348 self.SetMenuBar(self.mainmenu)
349
350 # set the menu accellerator table...
351 aTable = wxAcceleratorTable([(wxACCEL_ALT, ord('X'), exitID),
352 (wxACCEL_CTRL, ord('H'), helpID)])
353 self.SetAcceleratorTable(aTable)
354
355
356 # Create a TreeCtrl
357 tID = wxNewId()
358 self.treeMap = {}
359 self.tree = wxTreeCtrl(splitter, tID,
360 style=wxTR_HAS_BUTTONS |
361 wxTR_EDIT_LABELS |
362 wxTR_HAS_VARIABLE_ROW_HEIGHT)
363
364 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
365 root = self.tree.AddRoot("wxPython Overview")
366 firstChild = None
367 for item in _treeList:
368 child = self.tree.AppendItem(root, item[0])
369 if not firstChild: firstChild = child
370 for childItem in item[1]:
371 theDemo = self.tree.AppendItem(child, childItem)
372 self.treeMap[childItem] = theDemo
373
374 self.tree.Expand(root)
375 self.tree.Expand(firstChild)
376 EVT_TREE_ITEM_EXPANDED (self.tree, tID, self.OnItemExpanded)
377 EVT_TREE_ITEM_COLLAPSED (self.tree, tID, self.OnItemCollapsed)
378 EVT_TREE_SEL_CHANGED (self.tree, tID, self.OnSelChanged)
379 EVT_LEFT_DOWN (self.tree, self.OnTreeLeftDown)
380
381 # Create a Notebook
382 self.nb = wxNotebook(splitter2, -1, style=wxCLIP_CHILDREN)
383
384 # Set up a wxHtmlWindow on the Overview Notebook page
385 # we put it in a panel first because there seems to be a
386 # refresh bug of some sort (wxGTK) when it is directly in
387 # the notebook...
388 if 0: # the old way
389 self.ovr = wxHtmlWindow(self.nb, -1, size=(400, 400))
390 self.nb.AddPage(self.ovr, self.overviewText)
391
392 else: # hopefully I can remove this hacky code soon, see bug #216861
393 panel = wxPanel(self.nb, -1, style=wxCLIP_CHILDREN)
394 self.ovr = wxHtmlWindow(panel, -1, size=(400, 400))
395 self.nb.AddPage(panel, self.overviewText)
396
397 def OnOvrSize(evt, ovr=self.ovr):
398 ovr.SetSize(evt.GetSize())
399
400 EVT_SIZE(panel, OnOvrSize)
401 EVT_ERASE_BACKGROUND(panel, EmptyHandler)
402
403
404 self.SetOverview(self.overviewText, overview)
405
406
407 # Set up a TextCtrl on the Demo Code Notebook page
408 self.txt = wxTextCtrl(self.nb, -1,
409 style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
410 self.nb.AddPage(self.txt, "Demo Code")
411
412
413 # Set up a log on the View Log Notebook page
414 self.log = wxTextCtrl(splitter2, -1,
415 style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
416
417 # Set the wxWindows log target to be this textctrl
418 #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
419
420 # But instead of the above we want to show how to use our own wxLog class
421 wxLog_SetActiveTarget(MyLog(self.log))
422
423
424
425 self.Show(true)
426
427 # add the windows to the splitter and split it.
428 splitter2.SplitHorizontally(self.nb, self.log)
429 splitter.SplitVertically(self.tree, splitter2)
430
431 splitter.SetSashPosition(180, true)
432 splitter.SetMinimumPaneSize(20)
433 splitter2.SetSashPosition(450, true)
434 splitter2.SetMinimumPaneSize(20)
435
436
437
438 # select initial items
439 self.nb.SetSelection(0)
440 self.tree.SelectItem(root)
441
442 if len(sys.argv) == 2:
443 try:
444 selectedDemo = self.treeMap[sys.argv[1]]
445 except:
446 selectedDemo = None
447 if selectedDemo:
448 self.tree.SelectItem(selectedDemo)
449 self.tree.EnsureVisible(selectedDemo)
450
451
452 wxLogMessage('window handle: %s' % self.GetHandle())
453
454
455 #---------------------------------------------
456 def WriteText(self, text):
457 if text[-1:] == '\n':
458 text = text[:-1]
459 wxLogMessage(text)
460
461
462 def write(self, txt):
463 self.WriteText(txt)
464
465 #---------------------------------------------
466 def OnItemExpanded(self, event):
467 item = event.GetItem()
468 wxLogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
469 event.Skip()
470
471 #---------------------------------------------
472 def OnItemCollapsed(self, event):
473 item = event.GetItem()
474 wxLogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
475 event.Skip()
476
477 #---------------------------------------------
478 def OnTreeLeftDown(self, event):
479 pt = event.GetPosition();
480 item, flags = self.tree.HitTest(pt)
481 if item == self.tree.GetSelection():
482 self.SetOverview(self.tree.GetItemText(item)+" Overview", self.curOverview)
483 event.Skip()
484
485 #---------------------------------------------
486 def OnSelChanged(self, event):
487 if self.dying:
488 return
489
490 item = event.GetItem()
491 itemText = self.tree.GetItemText(item)
492 self.RunDemo(itemText)
493
494
495 #---------------------------------------------
496 def RunDemo(self, itemText):
497 os.chdir(self.cwd)
498 if self.nb.GetPageCount() == 3:
499 if self.nb.GetSelection() == 2:
500 self.nb.SetSelection(0)
501 self.nb.DeletePage(2)
502
503 if itemText == self.overviewText:
504 self.GetDemoFile('Main.py')
505 self.SetOverview(self.overviewText, overview)
506 self.nb.Refresh();
507 self.window = None
508
509 else:
510 if os.path.exists(itemText + '.py'):
511 wxBeginBusyCursor()
512 wxLogMessage("Running demo %s.py..." % itemText)
513 try:
514 self.GetDemoFile(itemText + '.py')
515 module = __import__(itemText, globals())
516 self.SetOverview(itemText + " Overview", module.overview)
517 finally:
518 wxEndBusyCursor()
519
520 # in case runTest is modal, make sure things look right...
521 self.nb.Refresh();
522 wxYield()
523
524 self.window = module.runTest(self, self.nb, self) ###
525 if self.window:
526 self.nb.AddPage(self.window, 'Demo')
527 wxYield()
528 self.nb.SetSelection(2)
529
530 else:
531 self.ovr.SetPage("")
532 self.txt.Clear()
533 self.window = None
534
535
536
537 #---------------------------------------------
538 # Get the Demo files
539 def GetDemoFile(self, filename):
540 self.txt.Clear()
541 try:
542 self.txt.SetValue(open(filename).read())
543 except IOError:
544 self.txt.WriteText("Cannot open %s file." % filename)
545
546 self.txt.SetInsertionPoint(0)
547 self.txt.ShowPosition(0)
548
549 #---------------------------------------------
550 def SetOverview(self, name, text):
551 self.curOverview = text
552 lead = text[:6]
553 if lead != '<html>' and lead != '<HTML>':
554 text = string.join(string.split(text, '\n'), '<br>')
555 self.ovr.SetPage(text)
556 self.nb.SetPageText(0, name)
557
558 #---------------------------------------------
559 # Menu methods
560 def OnFileExit(self, *event):
561 self.Close()
562
563
564 def OnHelpAbout(self, event):
565 from About import MyAboutBox
566 about = MyAboutBox(self)
567 about.ShowModal()
568 about.Destroy()
569
570
571 #---------------------------------------------
572 def OnCloseWindow(self, event):
573 self.dying = true
574 self.window = None
575 self.mainmenu = None
576 if hasattr(self, "tbicon"):
577 del self.tbicon
578 self.Destroy()
579
580
581 #---------------------------------------------
582 def OnIdle(self, event):
583 if self.otherWin:
584 self.otherWin.Raise()
585 self.window = self.otherWin
586 self.otherWin = None
587
588 if self.showTip:
589 self.ShowTip()
590 self.showTip = false
591
592
593 #---------------------------------------------
594 def ShowTip(self):
595 try:
596 showTipText = open(opj("data/showTips")).read()
597 showTip, index = eval(showTipText)
598 except IOError:
599 showTip, index = (1, 0)
600 if showTip:
601 tp = wxCreateFileTipProvider(opj("data/tips.txt"), index)
602 showTip = wxShowTip(self, tp)
603 index = tp.GetCurrentTip()
604 open(opj("data/showTips"), "w").write(str( (showTip, index) ))
605
606
607 #---------------------------------------------
608 def OnDemoMenu(self, event):
609 try:
610 selectedDemo = self.treeMap[self.mainmenu.GetLabel(event.GetId())]
611 except:
612 selectedDemo = None
613 if selectedDemo:
614 self.tree.SelectItem(selectedDemo)
615 self.tree.EnsureVisible(selectedDemo)
616
617
618 #---------------------------------------------
619 def OnTaskBarActivate(self, evt):
620 if self.IsIconized():
621 self.Iconize(false)
622 if not self.IsShown():
623 self.Show(true)
624 self.Raise()
625
626 #---------------------------------------------
627
628 TBMENU_RESTORE = 1000
629 TBMENU_CLOSE = 1001
630
631 def OnTaskBarMenu(self, evt):
632 menu = wxMenu()
633 menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
634 menu.Append(self.TBMENU_CLOSE, "Close")
635 self.tbicon.PopupMenu(menu)
636 menu.Destroy()
637
638 #---------------------------------------------
639 def OnTaskBarClose(self, evt):
640 self.Close()
641
642 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
643 # prod the main idle handler a bit to get the window to actually close
644 wxGetApp().ProcessIdle()
645
646
647 #---------------------------------------------
648 def OnIconfiy(self, evt):
649 wxLogMessage("OnIconfiy")
650 evt.Skip()
651
652 #---------------------------------------------
653 def OnMaximize(self, evt):
654 wxLogMessage("OnMaximize")
655 evt.Skip()
656
657
658
659
660 #---------------------------------------------------------------------------
661 #---------------------------------------------------------------------------
662
663 class MySplashScreen(wxSplashScreen):
664 def __init__(self):
665 bmp = wxImage(opj("bitmaps/splash.gif")).ConvertToBitmap()
666 wxSplashScreen.__init__(self, bmp,
667 wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT,
668 4000, None, -1)
669 EVT_CLOSE(self, self.OnClose)
670
671 def OnClose(self, evt):
672 frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
673 frame.Show(true)
674 evt.Skip() # Make sure the default handler runs too...
675
676
677 class MyApp(wxApp):
678 def OnInit(self):
679 """
680 Create and show the splash screen. It will then create and show
681 the main frame when it is time to do so.
682 """
683 wxInitAllImageHandlers()
684 splash = MySplashScreen()
685 splash.Show()
686 return true
687
688
689
690 #---------------------------------------------------------------------------
691
692 def main():
693 try:
694 demoPath = os.path.dirname(__file__)
695 os.chdir(demoPath)
696 except:
697 pass
698 app = MyApp(0)
699 app.MainLoop()
700
701
702 #---------------------------------------------------------------------------
703
704
705
706 overview = """<html><body>
707 <h2>Python</h2>
708
709 Python is an interpreted, interactive, object-oriented programming
710 language often compared to Tcl, Perl, Scheme, or Java.
711
712 <p> Python combines remarkable power with very clear syntax. It has
713 modules, classes, exceptions, very high level dynamic data types, and
714 dynamic typing. There are interfaces to many system calls and
715 libraries, and new built-in modules are easily written in C or
716 C++. Python is also usable as an extension language for applications
717 that need a programmable interface. <p>
718
719 <h2>wxWindows</h2>
720
721 wxWindows is a free C++ framework designed to make cross-platform
722 programming child's play. Well, almost. wxWindows 2 supports Windows
723 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
724 underway. Other ports are under consideration. <p>
725
726 wxWindows is a set of libraries that allows C++ applications to
727 compile and run on several different types of computers, with minimal
728 source code changes. There is one library per supported GUI (such as
729 Motif, or Windows). As well as providing a common API (Application
730 Programming Interface) for GUI functionality, it provides
731 functionality for accessing some commonly-used operating system
732 facilities, such as copying or deleting files. wxWindows is a
733 'framework' in the sense that it provides a lot of built-in
734 functionality, which the application can use or replace as required,
735 thus saving a great deal of coding effort. Basic data structures such
736 as strings, linked lists and hash tables are also supported.
737
738 <p>
739 <h2>wxPython</h2>
740
741 wxPython is a Python extension module that encapsulates the wxWindows
742 GUI classes. Currently it is only available for the Win32 and GTK
743 ports of wxWindows, but as soon as the other ports are brought up to
744 the same level as Win32 and GTK, it should be fairly trivial to
745 enable wxPython to be used with the new GUI.
746
747 <p>
748
749 The wxPython extension module attempts to mirror the class heiarchy
750 of wxWindows as closely as possible. This means that there is a
751 wxFrame class in wxPython that looks, smells, tastes and acts almost
752 the same as the wxFrame class in the C++ version. Unfortunately,
753 because of differences in the languages, wxPython doesn't match
754 wxWindows exactly, but the differences should be easy to absorb
755 because they are natural to Python. For example, some methods that
756 return multiple values via argument pointers in C++ will return a
757 tuple of values in Python.
758
759 <p>
760
761 There is still much to be done for wxPython, many classes still need
762 to be mirrored. Also, wxWindows is still somewhat of a moving target
763 so it is a bit of an effort just keeping wxPython up to date. On the
764 other hand, there are enough of the core classes completed that
765 useful applications can be written.
766
767 <p>
768
769 wxPython is close enough to the C++ version that the majority of
770 the wxPython documentation is actually just notes attached to the C++
771 documents that describe the places where wxPython is different. There
772 is also a series of sample programs included, and a series of
773 documentation pages that assist the programmer in getting started
774 with wxPython.
775
776 """
777
778
779 #----------------------------------------------------------------------------
780 #----------------------------------------------------------------------------
781
782 if __name__ == '__main__':
783 main()
784
785 #----------------------------------------------------------------------------
786
787
788
789
790
791
792