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
21 #---------------------------------------------------------------------------
25 ('New since last release', ['ContextHelp',
32 'wxFindReplaceDialog',
39 'wxDynamicSashWindow',
46 ('Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame',
47 'wxGrid', 'wxSashWindow',
48 'wxScrolledWindow', 'wxSplitterWindow',
49 'wxStatusBar', 'wxNotebook',
51 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',
53 'wxDynamicSashWindow',
56 ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
57 'wxSingleChoiceDialog', 'wxTextEntryDialog',
58 'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
59 'wxMessageDialog', 'wxProgressDialog', 'wxFindReplaceDialog',
62 ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
63 'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
64 'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
65 'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
66 'wxCalendarCtrl', 'wxToggleButton',
67 'wxEditableListBox', 'wxLEDNumberCtrl',
70 ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource']),
72 ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'URLDragAndDrop',
74 'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
75 'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
76 'PythonEvents', 'Threads',
77 'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
78 'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
79 'wxJoystick', 'DrawXXXList', 'ErrorDialogs', 'wxMimeTypesManager',
83 ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
84 'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
85 'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
86 'FileBrowseButton', 'GenericButtons', 'wxEditor',
87 'ColourSelect', 'ImageBrowser',
88 'infoframe', 'ColourDB', 'PyCrust', 'TablePrint',
92 ('Cool Contribs', ['pyTree', 'hangman',
99 #---------------------------------------------------------------------------
101 class MyLog(wxPyLog
):
102 def __init__(self
, textCtrl
, logTime
=0):
103 wxPyLog
.__init
__(self
)
105 self
.logTime
= logTime
107 def DoLogString(self
, message
, timeStamp
):
109 message
= time
.strftime("%X", time
.localtime(timeStamp
)) + \
111 self
.tc
.AppendText(message
+ '\n')
114 #---------------------------------------------------------------------------
116 class wxPythonDemo(wxFrame
):
118 def __init__(self
, parent
, id, title
):
119 wxFrame
.__init
__(self
, parent
, -1, title
, size
= (800, 600),
120 style
=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE
)
122 self
.cwd
= os
.getcwd()
123 self
.curOverview
= ""
126 icon
= wxIconFromXPMData(images
.getMondrianData())
128 # another way to do it
129 bmp
= images
.getMondrianBitmap()
131 icon
.CopyFromBitmap(bmp
)
135 if wxPlatform
== '__WXMSW__':
136 # setup a taskbar icon, and catch some events from it
137 self
.tbicon
= wxTaskBarIcon()
138 self
.tbicon
.SetIcon(icon
, "wxPython Demo")
139 EVT_TASKBAR_LEFT_DCLICK(self
.tbicon
, self
.OnTaskBarActivate
)
140 EVT_TASKBAR_RIGHT_UP(self
.tbicon
, self
.OnTaskBarMenu
)
141 EVT_MENU(self
.tbicon
, self
.TBMENU_RESTORE
, self
.OnTaskBarActivate
)
142 EVT_MENU(self
.tbicon
, self
.TBMENU_CLOSE
, self
.OnTaskBarClose
)
146 EVT_IDLE(self
, self
.OnIdle
)
147 EVT_CLOSE(self
, self
.OnCloseWindow
)
148 EVT_ICONIZE(self
, self
.OnIconfiy
)
149 EVT_MAXIMIZE(self
, self
.OnMaximize
)
152 self
.CreateStatusBar(1, wxST_SIZEGRIP
)
154 splitter
= wxSplitterWindow(self
, -1, style
=wxNO_3D|wxSP_3D
)
155 splitter2
= wxSplitterWindow(splitter
, -1, style
=wxNO_3D|wxSP_3D
)
157 def EmptyHandler(evt
): pass
158 EVT_ERASE_BACKGROUND(splitter
, EmptyHandler
)
159 EVT_ERASE_BACKGROUND(splitter2
, EmptyHandler
)
161 # Prevent TreeCtrl from displaying all items after destruction when true
165 self
.mainmenu
= wxMenuBar()
168 menu
.Append(exitID
, 'E&xit\tAlt-X', 'Get the heck outta here!')
169 EVT_MENU(self
, exitID
, self
.OnFileExit
)
170 self
.mainmenu
.Append(menu
, '&File')
174 for item
in _treeList
:
176 for childItem
in item
[1]:
178 submenu
.Append(mID
, childItem
)
179 EVT_MENU(self
, mID
, self
.OnDemoMenu
)
180 menu
.AppendMenu(wxNewId(), item
[0], submenu
)
181 self
.mainmenu
.Append(menu
, '&Demo')
187 menu
.Append(helpID
, '&About\tCtrl-H', 'wxPython RULES!!!')
188 EVT_MENU(self
, helpID
, self
.OnHelpAbout
)
189 self
.mainmenu
.Append(menu
, '&Help')
190 self
.SetMenuBar(self
.mainmenu
)
192 # set the menu accellerator table...
193 aTable
= wxAcceleratorTable([(wxACCEL_ALT
, ord('X'), exitID
),
194 (wxACCEL_CTRL
, ord('H'), helpID
)])
195 self
.SetAcceleratorTable(aTable
)
201 self
.tree
= wxTreeCtrl(splitter
, tID
,
202 style
=wxTR_HAS_BUTTONS |
204 wxTR_HAS_VARIABLE_ROW_HEIGHT |
206 #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
207 root
= self
.tree
.AddRoot("Overview")
209 for item
in _treeList
:
210 child
= self
.tree
.AppendItem(root
, item
[0])
211 if not firstChild
: firstChild
= child
212 for childItem
in item
[1]:
213 theDemo
= self
.tree
.AppendItem(child
, childItem
)
214 self
.treeMap
[childItem
] = theDemo
216 self
.tree
.Expand(root
)
217 self
.tree
.Expand(firstChild
)
218 EVT_TREE_ITEM_EXPANDED (self
.tree
, tID
, self
.OnItemExpanded
)
219 EVT_TREE_ITEM_COLLAPSED (self
.tree
, tID
, self
.OnItemCollapsed
)
220 EVT_TREE_SEL_CHANGED (self
.tree
, tID
, self
.OnSelChanged
)
221 EVT_LEFT_DOWN (self
.tree
, self
.OnTreeLeftDown
)
224 self
.nb
= wxNotebook(splitter2
, -1, style
=wxCLIP_CHILDREN
)
226 # Set up a wxHtmlWindow on the Overview Notebook page
227 # we put it in a panel first because there seems to be a
228 # refresh bug of some sort (wxGTK) when it is directly in
231 self
.ovr
= wxHtmlWindow(self
.nb
, -1, size
=(400, 400))
232 self
.nb
.AddPage(self
.ovr
, "Overview")
234 else: # hopefully I can remove this hacky code soon, see bug #216861
235 panel
= wxPanel(self
.nb
, -1, style
=wxCLIP_CHILDREN
)
236 self
.ovr
= wxHtmlWindow(panel
, -1, size
=(400, 400))
237 self
.nb
.AddPage(panel
, "Overview")
239 def OnOvrSize(evt
, ovr
=self
.ovr
):
240 ovr
.SetSize(evt
.GetSize())
242 EVT_SIZE(panel
, OnOvrSize
)
243 EVT_ERASE_BACKGROUND(panel
, EmptyHandler
)
246 self
.SetOverview("Overview", overview
)
249 # Set up a TextCtrl on the Demo Code Notebook page
250 self
.txt
= wxTextCtrl(self
.nb
, -1,
251 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
252 self
.nb
.AddPage(self
.txt
, "Demo Code")
255 # Set up a log on the View Log Notebook page
256 self
.log
= wxTextCtrl(splitter2
, -1,
257 style
= wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL
)
258 # Set the wxWindows log target to be this textctrl
259 #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
260 wxLog_SetActiveTarget(MyLog(self
.log
))
266 # add the windows to the splitter and split it.
267 splitter2
.SplitHorizontally(self
.nb
, self
.log
)
268 splitter2
.SetSashPosition(450, true
)
269 splitter2
.SetMinimumPaneSize(20)
271 splitter
.SplitVertically(self
.tree
, splitter2
)
272 splitter
.SetSashPosition(180, true
)
273 splitter
.SetMinimumPaneSize(20)
276 # select initial items
277 self
.nb
.SetSelection(0)
278 self
.tree
.SelectItem(root
)
280 if len(sys
.argv
) == 2:
282 selectedDemo
= self
.treeMap
[sys
.argv
[1]]
286 self
.tree
.SelectItem(selectedDemo
)
287 self
.tree
.EnsureVisible(selectedDemo
)
290 wxLogMessage('window handle: %s' % self
.GetHandle())
293 #---------------------------------------------
294 def WriteText(self
, text
):
295 if text
[-1:] == '\n':
300 def write(self
, txt
):
303 #---------------------------------------------
304 def OnItemExpanded(self
, event
):
305 item
= event
.GetItem()
306 wxLogMessage("OnItemExpanded: %s" % self
.tree
.GetItemText(item
))
309 #---------------------------------------------
310 def OnItemCollapsed(self
, event
):
311 item
= event
.GetItem()
312 wxLogMessage("OnItemCollapsed: %s" % self
.tree
.GetItemText(item
))
315 #---------------------------------------------
316 def OnTreeLeftDown(self
, event
):
317 pt
= event
.GetPosition();
318 item
, flags
= self
.tree
.HitTest(pt
)
319 if item
== self
.tree
.GetSelection():
320 self
.SetOverview(self
.tree
.GetItemText(item
), self
.curOverview
)
323 #---------------------------------------------
324 def OnSelChanged(self
, event
):
328 item
= event
.GetItem()
329 itemText
= self
.tree
.GetItemText(item
)
330 self
.RunDemo(itemText
)
333 #---------------------------------------------
334 def RunDemo(self
, itemText
):
336 if self
.nb
.GetPageCount() == 3:
337 if self
.nb
.GetSelection() == 2:
338 self
.nb
.SetSelection(0)
339 self
.nb
.DeletePage(2)
341 if itemText
== 'Overview':
342 self
.GetDemoFile('Main.py')
343 self
.SetOverview('Overview', overview
)
348 if os
.path
.exists(itemText
+ '.py'):
350 wxLogMessage("Running demo %s.py..." % itemText
)
352 self
.GetDemoFile(itemText
+ '.py')
353 module
= __import__(itemText
, globals())
354 self
.SetOverview(itemText
, module
.overview
)
358 # in case runTest is modal, make sure things look right...
362 self
.window
= module
.runTest(self
, self
.nb
, self
) ###
364 self
.nb
.AddPage(self
.window
, 'Demo')
366 self
.nb
.SetSelection(2)
375 #---------------------------------------------
377 def GetDemoFile(self
, filename
):
380 self
.txt
.SetValue(open(filename
).read())
382 self
.txt
.WriteText("Cannot open %s file." % filename
)
384 self
.txt
.SetInsertionPoint(0)
385 self
.txt
.ShowPosition(0)
387 #---------------------------------------------
388 def SetOverview(self
, name
, text
):
389 self
.curOverview
= text
391 if lead
!= '<html>' and lead
!= '<HTML>':
392 text
= string
.join(string
.split(text
, '\n'), '<br>')
393 #text = '<font size="-1"><pre>' + text + '</pre></font>'
394 self
.ovr
.SetPage(text
)
395 self
.nb
.SetPageText(0, name
)
397 #---------------------------------------------
399 def OnFileExit(self
, *event
):
403 def OnHelpAbout(self
, event
):
404 from About
import MyAboutBox
405 about
= MyAboutBox(self
)
410 #---------------------------------------------
411 def OnCloseWindow(self
, event
):
415 if hasattr(self
, "tbicon"):
420 #---------------------------------------------
421 def OnIdle(self
, event
):
423 self
.otherWin
.Raise()
424 self
.window
= self
.otherWin
427 #---------------------------------------------
428 def OnDemoMenu(self
, event
):
430 selectedDemo
= self
.treeMap
[self
.mainmenu
.GetLabel(event
.GetId())]
434 self
.tree
.SelectItem(selectedDemo
)
435 self
.tree
.EnsureVisible(selectedDemo
)
438 #---------------------------------------------
439 def OnTaskBarActivate(self
, evt
):
440 if self
.IsIconized():
442 if not self
.IsShown():
446 #---------------------------------------------
448 TBMENU_RESTORE
= 1000
451 def OnTaskBarMenu(self
, evt
):
453 menu
.Append(self
.TBMENU_RESTORE
, "Restore wxPython Demo")
454 menu
.Append(self
.TBMENU_CLOSE
, "Close")
455 self
.tbicon
.PopupMenu(menu
)
458 #---------------------------------------------
459 def OnTaskBarClose(self
, evt
):
462 # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
463 # prod the main idle handler a bit to get the window to actually close
464 wxGetApp().ProcessIdle()
467 #---------------------------------------------
468 def OnIconfiy(self
, evt
):
469 wxLogMessage("OnIconfiy")
472 #---------------------------------------------
473 def OnMaximize(self
, evt
):
474 wxLogMessage("OnMaximize")
480 #---------------------------------------------------------------------------
481 #---------------------------------------------------------------------------
483 class MySplashScreen(wxSplashScreen
):
485 bmp
= wxImage('bitmaps/splash.gif').ConvertToBitmap()
486 wxSplashScreen
.__init
__(self
, bmp
,
487 wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT
,
489 EVT_CLOSE(self
, self
.OnClose
)
491 def OnClose(self
, evt
):
492 frame
= wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
497 def ShowTip(self
, frame
):
499 showTipText
= open("data/showTips").read()
500 showTip
, index
= eval(showTipText
)
502 showTip
, index
= (1, 0)
504 tp
= wxCreateFileTipProvider("data/tips.txt", index
)
505 showTip
= wxShowTip(frame
, tp
)
506 index
= tp
.GetCurrentTip()
507 open("data/showTips", "w").write(str( (showTip
, index
) ))
514 Create and show the splash screen. It will then create and show
515 the main frame when it is time to do so.
517 wxInitAllImageHandlers()
518 splash
= MySplashScreen()
525 #---------------------------------------------------------------------------
529 demoPath
= os
.path
.dirname(__file__
)
537 #---------------------------------------------------------------------------
541 overview
= """<html><body>
544 Python is an interpreted, interactive, object-oriented programming
545 language often compared to Tcl, Perl, Scheme, or Java.
547 <p> Python combines remarkable power with very clear syntax. It has
548 modules, classes, exceptions, very high level dynamic data types, and
549 dynamic typing. There are interfaces to many system calls and
550 libraries, and new built-in modules are easily written in C or
551 C++. Python is also usable as an extension language for applications
552 that need a programmable interface. <p>
556 wxWindows is a free C++ framework designed to make cross-platform
557 programming child's play. Well, almost. wxWindows 2 supports Windows
558 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
559 underway. Other ports are under consideration. <p>
561 wxWindows is a set of libraries that allows C++ applications to
562 compile and run on several different types of computers, with minimal
563 source code changes. There is one library per supported GUI (such as
564 Motif, or Windows). As well as providing a common API (Application
565 Programming Interface) for GUI functionality, it provides
566 functionality for accessing some commonly-used operating system
567 facilities, such as copying or deleting files. wxWindows is a
568 'framework' in the sense that it provides a lot of built-in
569 functionality, which the application can use or replace as required,
570 thus saving a great deal of coding effort. Basic data structures such
571 as strings, linked lists and hash tables are also supported.
576 wxPython is a Python extension module that encapsulates the wxWindows
577 GUI classes. Currently it is only available for the Win32 and GTK
578 ports of wxWindows, but as soon as the other ports are brought up to
579 the same level as Win32 and GTK, it should be fairly trivial to
580 enable wxPython to be used with the new GUI.
584 The wxPython extension module attempts to mirror the class heiarchy
585 of wxWindows as closely as possible. This means that there is a
586 wxFrame class in wxPython that looks, smells, tastes and acts almost
587 the same as the wxFrame class in the C++ version. Unfortunately,
588 because of differences in the languages, wxPython doesn't match
589 wxWindows exactly, but the differences should be easy to absorb
590 because they are natural to Python. For example, some methods that
591 return multiple values via argument pointers in C++ will return a
592 tuple of values in Python.
596 There is still much to be done for wxPython, many classes still need
597 to be mirrored. Also, wxWindows is still somewhat of a moving target
598 so it is a bit of an effort just keeping wxPython up to date. On the
599 other hand, there are enough of the core classes completed that
600 useful applications can be written.
604 wxPython is close enough to the C++ version that the majority of
605 the wxPython documentation is actually just notes attached to the C++
606 documents that describe the places where wxPython is different. There
607 is also a series of sample programs included, and a series of
608 documentation pages that assist the programmer in getting started
614 #----------------------------------------------------------------------------
615 #----------------------------------------------------------------------------
617 if __name__
== '__main__':
620 #----------------------------------------------------------------------------