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"):
14
self.pos = wx.DefaultPosition
15
self.size = (450, 300)
18
def SetParent(self, parent):
19
"""Set the window to be used as the popup Frame's parent."""
23
def CreateOutputWindow(self, st):
24
self.frame = wx.Frame(self.parent, -1, self.title, self.pos, self.size,
25
style=wx.DEFAULT_FRAME_STYLE)
26
self.text = wx.TextCtrl(self.frame, -1, "",
27
style=wx.TE_MULTILINE|wx.TE_READONLY)
28
self.text.AppendText(st)
30
EVT_CLOSE(self.frame, self.OnCloseWindow)
33
def OnCloseWindow(self, event):
34
if self.frame is not None:
40
# These methods provide the file-like output behaviour.
41
def write(self, text):
43
Create the output window if needed and write the string to it.
44
If not called in the context of the gui thread then uses
45
CallAfter to do the work there.
47
if self.frame is None:
48
if not wx.Thread_IsMain():
49
wx.CallAfter(self.CreateOutputWindow, text)
51
self.CreateOutputWindow(text)
53
if not wx.Thread_IsMain():
54
wx.CallAfter(self.text.AppendText, text)
56
self.text.AppendText(text)
60
if self.frame is not None:
61
wx.CallAfter(self.frame.Close)
69
#----------------------------------------------------------------------
71
_defRedirect = (wx.Platform == '__WXMSW__' or wx.Platform == '__WXMAC__')
75
The ``wx.App`` class represents the application and is used to:
77
* bootstrap the wxPython system and initialize the underlying
79
* set and get application-wide properties
80
* implement the windowing system main message or event loop,
81
and to dispatch events to window instances
84
Every application must have a ``wx.App`` instance, and all
85
creation of UI objects should be delayed until after the
86
``wx.App`` object has been created in order to ensure that the gui
87
platform and wxWidgets have been fully initialized.
89
Normally you would derive from this class and implement an
90
``OnInit`` method that creates a frame and then calls
91
``self.SetTopWindow(frame)``.
93
:see: `wx.PySimpleApp` for a simpler app class that can be used
97
outputWindowClass = PyOnDemandOutputWindow
99
def __init__(self, redirect=_defRedirect, filename=None,
100
useBestVisual=False, clearSigInt=True):
102
Construct a ``wx.App`` object.
104
:param redirect: Should ``sys.stdout`` and ``sys.stderr`` be
105
redirected? Defaults to True on Windows and Mac, False
106
otherwise. If `filename` is None then output will be
107
redirected to a window that pops up as needed. (You can
108
control what kind of window is created for the output by
109
resetting the class variable ``outputWindowClass`` to a
110
class of your choosing.)
112
:param filename: The name of a file to redirect output to, if
115
:param useBestVisual: Should the app try to use the best
116
available visual provided by the system (only relevant on
117
systems that have more than one visual.) This parameter
118
must be used instead of calling `SetUseBestVisual` later
119
on because it must be set before the underlying GUI
120
toolkit is initialized.
122
:param clearSigInt: Should SIGINT be cleared? This allows the
123
app to terminate upon a Ctrl-C in the console like other
126
:note: You should override OnInit to do applicaition
127
initialization to ensure that the system, toolkit and
128
wxWidgets are fully initialized.
130
wx.PyApp.__init__(self)
132
if wx.Platform == "__WXMAC__":
135
if not MacOS.WMAvailable():
137
This program needs access to the screen. Please run with 'pythonw',
138
not 'python', and only when you are logged in on the main display of
146
# This has to be done before OnInit
147
self.SetUseBestVisual(useBestVisual)
149
# Set the default handler for SIGINT. This fixes a problem
150
# where if Ctrl-C is pressed in the console that started this
151
# app then it will not appear to do anything, (not even send
152
# KeyboardInterrupt???) but will later segfault on exit. By
153
# setting the default handler then the app will exit, as
154
# expected (depending on platform.)
158
signal.signal(signal.SIGINT, signal.SIG_DFL)
162
# Save and redirect the stdio to a window?
164
self.saveStdio = (_sys.stdout, _sys.stderr)
166
self.RedirectStdio(filename)
168
# Use Python's install prefix as the default
169
wx.StandardPaths.Get().SetInstallPrefix(_sys.prefix)
171
# This finishes the initialization of wxWindows and then calls
172
# the OnInit that should be present in the derived class
176
def __del__(self, destroy=wx.PyApp.__del__):
177
self.RestoreStdio() # Just in case the MainLoop was overridden
181
wx.PyApp.Destroy(self)
184
def SetTopWindow(self, frame):
185
"""Set the \"main\" top level window"""
187
self.stdioWin.SetParent(frame)
188
wx.PyApp.SetTopWindow(self, frame)
192
"""Execute the main GUI event loop"""
193
wx.PyApp.MainLoop(self)
197
def RedirectStdio(self, filename=None):
198
"""Redirect sys.stdout and sys.stderr to a file or a popup window."""
200
_sys.stdout = _sys.stderr = open(filename, 'a')
202
self.stdioWin = self.outputWindowClass()
203
_sys.stdout = _sys.stderr = self.stdioWin
206
def RestoreStdio(self):
208
_sys.stdout, _sys.stderr = self.saveStdio
213
def SetOutputWindowAttributes(self, title=None, pos=None, size=None):
215
Set the title, position and/or size of the output window if
216
the stdio has been redirected. This should be called before
217
any output would cause the output window to be created.
220
if title is not None:
221
self.stdioWin.title = title
223
self.stdioWin.pos = pos
225
self.stdioWin.size = size
230
# change from wx.PyApp_XX to wx.App_XX
231
App_GetMacSupportPCMenuShortcuts = _core_.PyApp_GetMacSupportPCMenuShortcuts
232
App_GetMacAboutMenuItemId = _core_.PyApp_GetMacAboutMenuItemId
233
App_GetMacPreferencesMenuItemId = _core_.PyApp_GetMacPreferencesMenuItemId
234
App_GetMacExitMenuItemId = _core_.PyApp_GetMacExitMenuItemId
235
App_GetMacHelpMenuTitleName = _core_.PyApp_GetMacHelpMenuTitleName
236
App_SetMacSupportPCMenuShortcuts = _core_.PyApp_SetMacSupportPCMenuShortcuts
237
App_SetMacAboutMenuItemId = _core_.PyApp_SetMacAboutMenuItemId
238
App_SetMacPreferencesMenuItemId = _core_.PyApp_SetMacPreferencesMenuItemId
239
App_SetMacExitMenuItemId = _core_.PyApp_SetMacExitMenuItemId
240
App_SetMacHelpMenuTitleName = _core_.PyApp_SetMacHelpMenuTitleName
241
App_GetComCtl32Version = _core_.PyApp_GetComCtl32Version
243
#----------------------------------------------------------------------------
245
class PySimpleApp(wx.App):
247
A simple application class. You can just create one of these and
248
then then make your top level windows later, and not have to worry
249
about OnInit. For example::
251
app = wx.PySimpleApp()
252
frame = wx.Frame(None, title='Hello World')
259
def __init__(self, redirect=False, filename=None,
260
useBestVisual=False, clearSigInt=True):
262
:see: `wx.App.__init__`
264
wx.App.__init__(self, redirect, filename, useBestVisual, clearSigInt)
271
# Is anybody using this one?
272
class PyWidgetTester(wx.App):
273
def __init__(self, size = (250, 100)):
275
wx.App.__init__(self, 0)
278
self.frame = wx.Frame(None, -1, "Widget Tester", pos=(0,0), size=self.size)
279
self.SetTopWindow(self.frame)
282
def SetWidget(self, widgetClass, *args, **kwargs):
283
w = widgetClass(self.frame, *args, **kwargs)
284
self.frame.Show(True)
286
#----------------------------------------------------------------------------
287
# DO NOT hold any other references to this object. This is how we
288
# know when to cleanup system resources that wxWidgets is holding. When
289
# the sys module is unloaded, the refcount on sys.__wxPythonCleanup
290
# goes to zero and it calls the wx.App_CleanUp function.
294
self.cleanup = _core_.App_CleanUp
298
_sys.__wxPythonCleanup = __wxPyCleanup()
300
## # another possible solution, but it gets called too early...
302
## atexit.register(_core_.wxApp_CleanUp)
305
#----------------------------------------------------------------------------