2 #----------------------------------------------------------------------------
4 # Purpose: Testing lots of stuff, controls, window types, etc.
8 # Created: A long time ago, in a galaxy far, far away...
10 # Copyright: (c) 1999 by Total Control Software
11 # Licence: wxWindows license
12 #----------------------------------------------------------------------------
15 from wxPython
.wx
import *
16 from wxPython
.lib
.splashscreen
import SplashScreen
17 from wxPython
.html
import wxHtmlWindow
19 #---------------------------------------------------------------------------
23 ('New since last release', ['ColourSelect', 'ImageBrowser',
26 ('Managed Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame']),
28 ('Non-Managed Windows', ['wxGrid', 'wxSashWindow',
29 'wxScrolledWindow', 'wxSplitterWindow',
30 'wxStatusBar', 'wxNotebook',
32 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',]),
34 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
35 'wxSingleChoiceDialog', 'wxTextEntryDialog',
36 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
37 'wxMessageDialog', 'wxProgressDialog']),
39 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
40 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
41 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
42 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
46 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', ]),
48 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'FontEnumerator',
49 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
50 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
51 'PythonEvents', 'Threads',
52 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
53 'wxDragImage', "wxProcess", "FancyText",
56 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
57 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
58 'PyShell', 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
59 'FileBrowseButton', 'GenericButtons', 'wxEditor',
60 'PyShellWindow', 'ColourSelect', 'ImageBrowser',
63 ('Cool Contribs', ['pyTree', 'hangman', 'SlashDot', 'XMLtreeview']),
67 #---------------------------------------------------------------------------
69 class wxPythonDemo(wxFrame
):
71 def __init__(self
, parent
, id, title
):
72 wxFrame
.__init
__(self
, parent
, -1, title
, size
= (800, 600),
73 style
=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE
)
75 self
.cwd
= os
.getcwd()
78 if wxPlatform
== '__WXMSW__':
79 icon
= wxIcon('bitmaps/mondrian.ico', wxBITMAP_TYPE_ICO
)
82 # setup a taskbar icon, and catch some events from it
83 self
.tbicon
= wxTaskBarIcon()
84 self
.tbicon
.SetIcon(icon
, "wxPython Demo")
85 EVT_TASKBAR_LEFT_DCLICK(self
.tbicon
, self
.OnTaskBarActivate
)
86 EVT_TASKBAR_RIGHT_UP(self
.tbicon
, self
.OnTaskBarMenu
)
87 EVT_MENU(self
.tbicon
, self
.TBMENU_RESTORE
, self
.OnTaskBarActivate
)
88 EVT_MENU(self
.tbicon
, self
.TBMENU_CLOSE
, self
.OnTaskBarClose
)
92 EVT_IDLE(self
, self
.OnIdle
)
93 EVT_CLOSE(self
, self
.OnCloseWindow
)
94 EVT_ICONIZE(self
, self
.OnIconfiy
)
95 EVT_MAXIMIZE(self
, self
.OnMaximize
)
98 self
.CreateStatusBar(1, wxST_SIZEGRIP
)
100 splitter
= wxSplitterWindow(self
, -1, style
=wxNO_3D|wxSP_3D
)
101 splitter2
= wxSplitterWindow(splitter
, -1, style
=wxNO_3D|wxSP_3D
)
104 # Prevent TreeCtrl from displaying all items after destruction
108 self
.mainmenu
= wxMenuBar()
111 menu
.Append(exitID
, 'E&xit\tAlt-X', 'Get the heck outta here!')
112 EVT_MENU(self
, exitID
, self
.OnFileExit
)
113 self
.mainmenu
.Append(menu
, '&File')
117 for item
in _treeList
:
119 for childItem
in item
[1]:
121 submenu
.Append(mID
, childItem
)
122 EVT_MENU(self
, mID
, self
.OnDemoMenu
)
123 menu
.AppendMenu(wxNewId(), item
[0], submenu
)
124 self
.mainmenu
.Append(menu
, '&Demo')
130 menu
.Append(helpID
, '&About\tCtrl-H', 'wxPython RULES!!!')
131 EVT_MENU(self
, helpID
, self
.OnHelpAbout
)
132 self
.mainmenu
.Append(menu
, '&Help')
133 self
.SetMenuBar(self
.mainmenu
)
135 # set the menu accellerator table...
136 aTable
= wxAcceleratorTable([(wxACCEL_ALT
, ord('X'), exitID
),
137 (wxACCEL_CTRL
, ord('H'), helpID
)])
138 self
.SetAcceleratorTable(aTable
)
144 self
.tree
= wxTreeCtrl(splitter
, tID
,
145 style
=wxTR_HAS_BUTTONS |
147 wxTR_HAS_VARIABLE_ROW_HEIGHT |
149 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
150 root
= self
.tree
.AddRoot("Overview")
152 for item
in _treeList
:
153 child
= self
.tree
.AppendItem(root
, item
[0])
154 if not firstChild
: firstChild
= child
155 for childItem
in item
[1]:
156 theDemo
= self
.tree
.AppendItem(child
, childItem
)
157 self
.treeMap
[childItem
] = theDemo
159 self
.tree
.Expand(root
)
160 self
.tree
.Expand(firstChild
)
161 EVT_TREE_ITEM_EXPANDED (self
.tree
, tID
, self
.OnItemExpanded
)
162 EVT_TREE_ITEM_COLLAPSED (self
.tree
, tID
, self
.OnItemCollapsed
)
163 EVT_TREE_SEL_CHANGED (self
.tree
, tID
, self
.OnSelChanged
)
164 EVT_LEFT_DOWN (self
.tree
, self
.OnTreeLeftDown
)
167 self
.nb
= wxNotebook(splitter2
, -1)
169 # Set up a wxHtmlWindow on the Overview Notebook page
170 # we put it in a panel first because there seems to be a
171 # refresh bug of some sort (wxGTK) when it is directly in
174 self
.ovr
= wxHtmlWindow(self
.nb
, -1, size
=(400, 400))
175 self
.nb
.AddPage(self
.ovr
, "Overview")
177 else: # hopefully I can remove this hacky code soon, see bug #216861
178 panel
= wxPanel(self
.nb
, -1)
179 self
.ovr
= wxHtmlWindow(panel
, -1, size
=(400, 400))
180 self
.nb
.AddPage(panel
, "Overview")
182 def OnOvrSize(evt
, ovr
=self
.ovr
):
183 ovr
.SetSize(evt
.GetSize())
185 EVT_SIZE(panel
, OnOvrSize
)
187 self
.SetOverview("Overview", overview
)
190 # Set up a TextCtrl on the Demo Code Notebook page
191 self
.txt
= wxTextCtrl(self
.nb
, -1,
192 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
193 self
.txt
.SetFont(wxFont(9, wxMODERN
, wxNORMAL
, wxNORMAL
, false
))
194 self
.nb
.AddPage(self
.txt
, "Demo Code")
197 # Set up a log on the View Log Notebook page
198 self
.log
= wxTextCtrl(splitter2
, -1,
199 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
200 # Set the wxWindows log target to be this textctrl
201 wxLog_SetActiveTarget(wxLogTextCtrl(self
.log
))
207 # add the windows to the splitter and split it.
208 splitter2
.SplitHorizontally(self
.nb
, self
.log
)
209 splitter2
.SetSashPosition(450, true
)
210 splitter2
.SetMinimumPaneSize(20)
212 splitter
.SplitVertically(self
.tree
, splitter2
)
213 splitter
.SetSashPosition(180, true
)
214 splitter
.SetMinimumPaneSize(20)
217 # select initial items
218 self
.nb
.SetSelection(0)
219 self
.tree
.SelectItem(root
)
221 if len(sys
.argv
) == 2:
223 selectedDemo
= self
.treeMap
[sys
.argv
[1]]
227 self
.tree
.SelectItem(selectedDemo
)
228 self
.tree
.EnsureVisible(selectedDemo
)
231 wxLogMessage('window handle: %s' % self
.GetHandle())
234 #---------------------------------------------
235 def WriteText(self
, text
):
236 if text
[-1:] == '\n':
241 def write(self
, txt
):
244 #---------------------------------------------
245 def OnItemExpanded(self
, event
):
246 item
= event
.GetItem()
247 wxLogMessage("OnItemExpanded: %s" % self
.tree
.GetItemText(item
))
250 #---------------------------------------------
251 def OnItemCollapsed(self
, event
):
252 item
= event
.GetItem()
253 wxLogMessage("OnItemCollapsed: %s" % self
.tree
.GetItemText(item
))
256 #---------------------------------------------
257 def OnTreeLeftDown(self
, event
):
258 pt
= event
.GetPosition();
259 item
, flags
= self
.tree
.HitTest(pt
)
260 if item
== self
.tree
.GetSelection():
261 self
.SetOverview(self
.tree
.GetItemText(item
), self
.curOverview
)
264 #---------------------------------------------
265 def OnSelChanged(self
, event
):
269 item
= event
.GetItem()
270 itemText
= self
.tree
.GetItemText(item
)
271 self
.RunDemo(itemText
)
274 #---------------------------------------------
275 def RunDemo(self
, itemText
):
277 if self
.nb
.GetPageCount() == 3:
278 if self
.nb
.GetSelection() == 2:
279 self
.nb
.SetSelection(0)
280 self
.nb
.DeletePage(2)
282 if itemText
== 'Overview':
283 self
.GetDemoFile('Main.py')
284 self
.SetOverview('Overview', overview
)
289 if os
.path
.exists(itemText
+ '.py'):
291 wxLogMessage("Running demo %s.py..." % itemText
)
293 self
.GetDemoFile(itemText
+ '.py')
294 module
= __import__(itemText
, globals())
295 self
.SetOverview(itemText
, module
.overview
)
299 # in case runTest is modal, make sure things look right...
303 self
.window
= module
.runTest(self
, self
.nb
, self
) ###
305 self
.nb
.AddPage(self
.window
, 'Demo')
307 self
.nb
.SetSelection(2)
316 #---------------------------------------------
318 def GetDemoFile(self
, filename
):
321 self
.txt
.SetValue(open(filename
).read())
323 self
.txt
.WriteText("Cannot open %s file." % filename
)
325 self
.txt
.SetInsertionPoint(0)
326 self
.txt
.ShowPosition(0)
328 #---------------------------------------------
329 def SetOverview(self
, name
, text
):
330 self
.curOverview
= text
332 if lead
!= '<html>' and lead
!= '<HTML>':
333 text
= string
.join(string
.split(text
, '\n'), '<br>')
334 #text = '<font size="-1"><pre>' + text + '</pre></font>'
335 self
.ovr
.SetPage(text
)
336 self
.nb
.SetPageText(0, name
)
338 #---------------------------------------------
340 def OnFileExit(self
, *event
):
344 def OnHelpAbout(self
, event
):
345 from About
import MyAboutBox
346 about
= MyAboutBox(self
)
351 #---------------------------------------------
352 def OnCloseWindow(self
, event
):
356 if hasattr(self
, "tbicon"):
361 #---------------------------------------------
362 def OnIdle(self
, event
):
364 self
.otherWin
.Raise()
365 self
.window
= self
.otherWin
368 #---------------------------------------------
369 def OnDemoMenu(self
, event
):
371 selectedDemo
= self
.treeMap
[self
.mainmenu
.GetLabel(event
.GetId())]
375 self
.tree
.SelectItem(selectedDemo
)
376 self
.tree
.EnsureVisible(selectedDemo
)
379 #---------------------------------------------
380 def OnTaskBarActivate(self
, evt
):
381 if self
.IsIconized():
383 if not self
.IsShown():
387 #---------------------------------------------
389 TBMENU_RESTORE
= 1000
392 def OnTaskBarMenu(self
, evt
):
394 menu
.Append(self
.TBMENU_RESTORE
, "Restore wxPython Demo")
395 menu
.Append(self
.TBMENU_CLOSE
, "Close")
396 self
.tbicon
.PopupMenu(menu
)
399 #---------------------------------------------
400 def OnTaskBarClose(self
, evt
):
403 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
404 # prod the main idle handler a bit to get the window to actually close
405 wxGetApp().ProcessIdle()
408 #---------------------------------------------
409 def OnIconfiy(self
, evt
):
410 wxLogMessage("OnIconfiy")
413 #---------------------------------------------
414 def OnMaximize(self
, evt
):
415 wxLogMessage("OnMaximize")
421 #---------------------------------------------------------------------------
422 #---------------------------------------------------------------------------
426 wxInitAllImageHandlers()
428 self
.splash
= SplashScreen(None, bitmapfile
='bitmaps/splash.gif',
429 duration
=4000, callback
=self
.AfterSplash
)
430 self
.splash
.Show(true
)
435 def AfterSplash(self
):
436 self
.splash
.Close(true
)
437 frame
= wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
439 self
.SetTopWindow(frame
)
443 def ShowTip(self
, frame
):
445 showTipText
= open("data/showTips").read()
446 showTip
, index
= eval(showTipText
)
448 showTip
, index
= (1, 0)
449 #print showTip, index
451 tp
= wxCreateFileTipProvider("data/tips.txt", index
)
452 showTip
= wxShowTip(frame
, tp
)
453 index
= tp
.GetCurrentTip()
454 open("data/showTips", "w").write(str( (showTip
, index
) ))
457 #---------------------------------------------------------------------------
461 demoPath
= os
.path
.split(__file__
)[0]
469 #---------------------------------------------------------------------------
473 overview
= """<html><body>
476 Python is an interpreted, interactive, object-oriented programming
477 language often compared to Tcl, Perl, Scheme, or Java.
479 <p> Python combines remarkable power with very clear syntax. It has
480 modules, classes, exceptions, very high level dynamic data types, and
481 dynamic typing. There are interfaces to many system calls and
482 libraries, and new built-in modules are easily written in C or
483 C++. Python is also usable as an extension language for applications
484 that need a programmable interface. <p>
488 wxWindows is a free C++ framework designed to make cross-platform
489 programming child's play. Well, almost. wxWindows 2 supports Windows
490 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
491 underway. Other ports are under consideration. <p>
493 wxWindows is a set of libraries that allows C++ applications to
494 compile and run on several different types of computers, with minimal
495 source code changes. There is one library per supported GUI (such as
496 Motif, or Windows). As well as providing a common API (Application
497 Programming Interface) for GUI functionality, it provides
498 functionality for accessing some commonly-used operating system
499 facilities, such as copying or deleting files. wxWindows is a
500 'framework' in the sense that it provides a lot of built-in
501 functionality, which the application can use or replace as required,
502 thus saving a great deal of coding effort. Basic data structures such
503 as strings, linked lists and hash tables are also supported.
508 wxPython is a Python extension module that encapsulates the wxWindows
509 GUI classes. Currently it is only available for the Win32 and GTK
510 ports of wxWindows, but as soon as the other ports are brought up to
511 the same level as Win32 and GTK, it should be fairly trivial to
512 enable wxPython to be used with the new GUI.
516 The wxPython extension module attempts to mirror the class heiarchy
517 of wxWindows as closely as possible. This means that there is a
518 wxFrame class in wxPython that looks, smells, tastes and acts almost
519 the same as the wxFrame class in the C++ version. Unfortunately,
520 because of differences in the languages, wxPython doesn't match
521 wxWindows exactly, but the differences should be easy to absorb
522 because they are natural to Python. For example, some methods that
523 return multiple values via argument pointers in C++ will return a
524 tuple of values in Python.
528 There is still much to be done for wxPython, many classes still need
529 to be mirrored. Also, wxWindows is still somewhat of a moving target
530 so it is a bit of an effort just keeping wxPython up to date. On the
531 other hand, there are enough of the core classes completed that
532 useful applications can be written.
536 wxPython is close enough to the C++ version that the majority of
537 the wxPython documentation is actually just notes attached to the C++
538 documents that describe the places where wxPython is different. There
539 is also a series of sample programs included, and a series of
540 documentation pages that assist the programmer in getting started
546 #----------------------------------------------------------------------------
547 #----------------------------------------------------------------------------
549 if __name__
== '__main__':
552 #----------------------------------------------------------------------------