2 #----------------------------------------------------------------------
4 class PyOnDemandOutputWindow
:
6 A class that can be used for redirecting Python's stdout and
7 stderr streams. It will do nothing until something is wrriten to
8 the stream at which point it will create a Frame with a text area
9 and write the text there.
11 def __init__(self
, title
= "wxPython: stdout/stderr"):
16 def SetParent(self
, parent
):
17 """Set the window to be used as the popup Frame's parent."""
21 def CreateOutputWindow(self
, st
):
22 self
.frame
= wx
.Frame(self
.parent
, -1, self
.title
,
23 style
=wx
.DEFAULT_FRAME_STYLE | wx
.NO_FULL_REPAINT_ON_RESIZE
)
24 self
.text
= wx
.TextCtrl(self
.frame
, -1, "",
25 style
= wx
.TE_MULTILINE | wx
.TE_READONLY
)
26 self
.text
.AppendText(st
)
27 self
.frame
.SetSize((450, 300))
29 EVT_CLOSE(self
.frame
, self
.OnCloseWindow
)
32 def OnCloseWindow(self
, event
):
33 if self
.frame
is not None:
39 # These methods provide the file-like output behaviour.
40 def write(self
, text
):
42 Create the output window if needed and write the string to it.
43 If not called in the context of the gui thread then uses
44 CallAfter to do the work there.
46 if self
.frame
is None:
47 if not wx
.Thread_IsMain():
48 wx
.CallAfter(self
.CreateOutputWindow
, text
)
50 self
.CreateOutputWindow(text
)
52 if not wx
.Thread_IsMain():
53 wx
.CallAfter(self
.text
.AppendText
, text
)
55 self
.text
.AppendText(text
)
59 if self
.frame
is not None:
60 wx
.CallAfter(self
.frame
.Close
)
64 #----------------------------------------------------------------------
66 _defRedirect
= (wx
.Platform
== '__WXMSW__' or wx
.Platform
== '__WXMAC__')
70 The main application class. Derive from this and implement an OnInit
71 method that creates a frame and then calls self.SetTopWindow(frame)
73 outputWindowClass
= PyOnDemandOutputWindow
75 def __init__(self
, redirect
=_defRedirect
, filename
=None, useBestVisual
=False):
76 wx
.PyApp
.__init
__(self
)
78 if wx
.Platform
== "__WXMAC__":
81 if not MacOS
.WMAvailable():
83 This program needs access to the screen. Please run with 'pythonw',
84 not 'python', and only when you are logged in on the main display of
90 # This has to be done before OnInit
91 self
.SetUseBestVisual(useBestVisual
)
93 # Set the default handler for SIGINT. This fixes a problem
94 # where if Ctrl-C is pressed in the console that started this
95 # app then it will not appear to do anything, (not even send
96 # KeyboardInterrupt???) but will later segfault on exit. By
97 # setting the default handler then the app will exit, as
98 # expected (depending on platform.)
101 signal
.signal(signal
.SIGINT
, signal
.SIG_DFL
)
105 # Save and redirect the stdio to a window?
107 self
.saveStdio
= (_sys
.stdout
, _sys
.stderr
)
109 self
.RedirectStdio(filename
)
111 # This finishes the initialization of wxWindows and then calls
112 # the OnInit that should be present in the derived class
118 self
.RestoreStdio() # Just in case the MainLoop was overridden
123 def SetTopWindow(self
, frame
):
124 """Set the \"main\" top level window"""
126 self
.stdioWin
.SetParent(frame
)
127 wx
.PyApp
.SetTopWindow(self
, frame
)
131 """Execute the main GUI event loop"""
132 wx
.PyApp
.MainLoop(self
)
136 def RedirectStdio(self
, filename
=None):
137 """Redirect sys.stdout and sys.stderr to a file or a popup window."""
139 _sys
.stdout
= _sys
.stderr
= open(filename
, 'a')
141 self
.stdioWin
= self
.outputWindowClass()
142 _sys
.stdout
= _sys
.stderr
= self
.stdioWin
145 def RestoreStdio(self
):
146 _sys
.stdout
, _sys
.stderr
= self
.saveStdio
150 # change from wxPyApp_ to wxApp_
151 App_GetMacSupportPCMenuShortcuts
= _core
.PyApp_GetMacSupportPCMenuShortcuts
152 App_GetMacAboutMenuItemId
= _core
.PyApp_GetMacAboutMenuItemId
153 App_GetMacPreferencesMenuItemId
= _core
.PyApp_GetMacPreferencesMenuItemId
154 App_GetMacExitMenuItemId
= _core
.PyApp_GetMacExitMenuItemId
155 App_GetMacHelpMenuTitleName
= _core
.PyApp_GetMacHelpMenuTitleName
156 App_SetMacSupportPCMenuShortcuts
= _core
.PyApp_SetMacSupportPCMenuShortcuts
157 App_SetMacAboutMenuItemId
= _core
.PyApp_SetMacAboutMenuItemId
158 App_SetMacPreferencesMenuItemId
= _core
.PyApp_SetMacPreferencesMenuItemId
159 App_SetMacExitMenuItemId
= _core
.PyApp_SetMacExitMenuItemId
160 App_SetMacHelpMenuTitleName
= _core
.PyApp_SetMacHelpMenuTitleName
161 App_GetComCtl32Version
= _core
.PyApp_GetComCtl32Version
163 #----------------------------------------------------------------------------
165 class PySimpleApp(wx
.App
):
167 A simple application class. You can just create one of these and
168 then then make your top level windows later, and not have to worry
171 def __init__(self
, redirect
=False, filename
=None, useBestVisual
=False):
172 wx
.App
.__init
__(self
, redirect
, filename
, useBestVisual
)
175 wx
.InitAllImageHandlers()
179 # Is anybody using this one?
180 class PyWidgetTester(wx
.App
):
181 def __init__(self
, size
= (250, 100)):
183 wx
.App
.__init
__(self
, 0)
186 self
.frame
= wx
.Frame(None, -1, "Widget Tester", pos
=(0,0), size
=self
.size
)
187 self
.SetTopWindow(self
.frame
)
190 def SetWidget(self
, widgetClass
, *args
):
191 w
= widgetClass(self
.frame
, *args
)
192 self
.frame
.Show(True)
194 #----------------------------------------------------------------------------
195 # DO NOT hold any other references to this object. This is how we
196 # know when to cleanup system resources that wxWin is holding. When
197 # the sys module is unloaded, the refcount on sys.__wxPythonCleanup
198 # goes to zero and it calls the wxApp_CleanUp function.
202 self
.cleanup
= _core
.App_CleanUp
206 _sys
.__wxPythonCleanup
= __wxPyCleanup()
208 ## # another possible solution, but it gets called too early...
209 ## if sys.version[0] == '2':
211 ## atexit.register(_core.wxApp_CleanUp)
213 ## sys.exitfunc = _core.wxApp_CleanUp
216 #----------------------------------------------------------------------------