]> git.saurik.com Git - wxWidgets.git/blob - wxPython/src/_app_ex.py
removed a debugging print
[wxWidgets.git] / wxPython / src / _app_ex.py
1
2 #----------------------------------------------------------------------
3
4 class PyOnDemandOutputWindow:
5 """
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.
10 """
11 def __init__(self, title = "wxPython: stdout/stderr"):
12 self.frame = None
13 self.title = title
14 self.parent = None
15
16 def SetParent(self, parent):
17 """Set the window to be used as the popup Frame's parent."""
18 self.parent = parent
19
20
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))
28 self.frame.Show(True)
29 EVT_CLOSE(self.frame, self.OnCloseWindow)
30
31
32 def OnCloseWindow(self, event):
33 if self.frame is not None:
34 self.frame.Destroy()
35 self.frame = None
36 self.text = None
37
38
39 # These methods provide the file-like output behaviour.
40 def write(self, text):
41 """
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.
45 """
46 if self.frame is None:
47 if not wx.Thread_IsMain():
48 wx.CallAfter(self.CreateOutputWindow, text)
49 else:
50 self.CreateOutputWindow(text)
51 else:
52 if not wx.Thread_IsMain():
53 wx.CallAfter(self.text.AppendText, text)
54 else:
55 self.text.AppendText(text)
56
57
58 def close(self):
59 if self.frame is not None:
60 wx.CallAfter(self.frame.Close)
61
62
63
64 #----------------------------------------------------------------------
65
66 _defRedirect = (wx.Platform == '__WXMSW__' or wx.Platform == '__WXMAC__')
67
68 class App(wx.PyApp):
69 """
70 The ``wx.App`` class represents the application and is used to:
71
72 * bootstrap the wxPython system and initialize the underlying
73 gui toolkit
74 * set and get application-wide properties
75 * implement the windowing system main message or event loop,
76 and to dispatch events to window instances
77 * etc.
78
79 Every application must have a ``wx.App`` instance, and all
80 creation of UI objects should be delayed until after the
81 ``wx.App`` object has been created in order to ensure that the gui
82 platform and wxWidgets have been fully initialized.
83
84 Normally you would derive from this class and implement an
85 ``OnInit`` method that creates a frame and then calls
86 ``self.SetTopWindow(frame)``.
87
88 :see: `wx.PySimpleApp` for a simpler app class that can be used
89 directly.
90 """
91
92 outputWindowClass = PyOnDemandOutputWindow
93
94 def __init__(self, redirect=_defRedirect, filename=None,
95 useBestVisual=False, clearSigInt=True):
96 """
97 Construct a ``wx.App`` object.
98
99 :param redirect: Should ``sys.stdout`` and ``sys.stderr`` be
100 redirected? Defaults to True on Windows and Mac, False
101 otherwise. If `filename` is None then output will be
102 redirected to a window that pops up as needed. (You can
103 control what kind of window is created for the output by
104 resetting the class variable ``outputWindowClass`` to a
105 class of your choosing.)
106
107 :param filename: The name of a file to redirect output to, if
108 redirect is True.
109
110 :param useBestVisual: Should the app try to use the best
111 available visual provided by the system (only relevant on
112 systems that have more than one visual.) This parameter
113 must be used instead of calling `SetUseBestVisual` later
114 on because it must be set before the underlying GUI
115 toolkit is initialized.
116
117 :param clearSigInt: Should SIGINT be cleared? This allows the
118 app to terminate upon a Ctrl-C in the console like other
119 GUI apps will.
120
121 :note: You should override OnInit to do applicaition
122 initialization to ensure that the system, toolkit and
123 wxWidgets are fully initialized.
124 """
125 wx.PyApp.__init__(self)
126
127 if wx.Platform == "__WXMAC__":
128 try:
129 import MacOS
130 if not MacOS.WMAvailable():
131 print """\
132 This program needs access to the screen. Please run with 'pythonw',
133 not 'python', and only when you are logged in on the main display of
134 your Mac."""
135 _sys.exit(1)
136 except:
137 pass
138
139 # This has to be done before OnInit
140 self.SetUseBestVisual(useBestVisual)
141
142 # Set the default handler for SIGINT. This fixes a problem
143 # where if Ctrl-C is pressed in the console that started this
144 # app then it will not appear to do anything, (not even send
145 # KeyboardInterrupt???) but will later segfault on exit. By
146 # setting the default handler then the app will exit, as
147 # expected (depending on platform.)
148 if clearSigInt:
149 try:
150 import signal
151 signal.signal(signal.SIGINT, signal.SIG_DFL)
152 except:
153 pass
154
155 # Save and redirect the stdio to a window?
156 self.stdioWin = None
157 self.saveStdio = (_sys.stdout, _sys.stderr)
158 if redirect:
159 self.RedirectStdio(filename)
160
161 # This finishes the initialization of wxWindows and then calls
162 # the OnInit that should be present in the derived class
163 self._BootstrapApp()
164
165
166 def __del__(self):
167 try:
168 self.RestoreStdio() # Just in case the MainLoop was overridden
169 except:
170 pass
171
172
173 def SetTopWindow(self, frame):
174 """Set the \"main\" top level window"""
175 if self.stdioWin:
176 self.stdioWin.SetParent(frame)
177 wx.PyApp.SetTopWindow(self, frame)
178
179
180 def MainLoop(self):
181 """Execute the main GUI event loop"""
182 wx.PyApp.MainLoop(self)
183 self.RestoreStdio()
184
185
186 def RedirectStdio(self, filename=None):
187 """Redirect sys.stdout and sys.stderr to a file or a popup window."""
188 if filename:
189 _sys.stdout = _sys.stderr = open(filename, 'a')
190 else:
191 self.stdioWin = self.outputWindowClass()
192 _sys.stdout = _sys.stderr = self.stdioWin
193
194
195 def RestoreStdio(self):
196 _sys.stdout, _sys.stderr = self.saveStdio
197
198
199
200 # change from wx.PyApp_XX to wx.App_XX
201 App_GetMacSupportPCMenuShortcuts = _core_.PyApp_GetMacSupportPCMenuShortcuts
202 App_GetMacAboutMenuItemId = _core_.PyApp_GetMacAboutMenuItemId
203 App_GetMacPreferencesMenuItemId = _core_.PyApp_GetMacPreferencesMenuItemId
204 App_GetMacExitMenuItemId = _core_.PyApp_GetMacExitMenuItemId
205 App_GetMacHelpMenuTitleName = _core_.PyApp_GetMacHelpMenuTitleName
206 App_SetMacSupportPCMenuShortcuts = _core_.PyApp_SetMacSupportPCMenuShortcuts
207 App_SetMacAboutMenuItemId = _core_.PyApp_SetMacAboutMenuItemId
208 App_SetMacPreferencesMenuItemId = _core_.PyApp_SetMacPreferencesMenuItemId
209 App_SetMacExitMenuItemId = _core_.PyApp_SetMacExitMenuItemId
210 App_SetMacHelpMenuTitleName = _core_.PyApp_SetMacHelpMenuTitleName
211 App_GetComCtl32Version = _core_.PyApp_GetComCtl32Version
212
213 #----------------------------------------------------------------------------
214
215 class PySimpleApp(wx.App):
216 """
217 A simple application class. You can just create one of these and
218 then then make your top level windows later, and not have to worry
219 about OnInit. For example::
220
221 app = wx.PySimpleApp()
222 frame = wx.Frame(None, title='Hello World')
223 frame.Show()
224 app.MainLoop()
225
226 :see: `wx.App`
227 """
228
229 def __init__(self, redirect=False, filename=None,
230 useBestVisual=False, clearSigInt=True):
231 """
232 :see: `wx.App.__init__`
233 """
234 wx.App.__init__(self, redirect, filename, useBestVisual, clearSigInt)
235
236 def OnInit(self):
237 wx.InitAllImageHandlers()
238 return True
239
240
241
242 # Is anybody using this one?
243 class PyWidgetTester(wx.App):
244 def __init__(self, size = (250, 100)):
245 self.size = size
246 wx.App.__init__(self, 0)
247
248 def OnInit(self):
249 self.frame = wx.Frame(None, -1, "Widget Tester", pos=(0,0), size=self.size)
250 self.SetTopWindow(self.frame)
251 return True
252
253 def SetWidget(self, widgetClass, *args, **kwargs):
254 w = widgetClass(self.frame, *args, **kwargs)
255 self.frame.Show(True)
256
257 #----------------------------------------------------------------------------
258 # DO NOT hold any other references to this object. This is how we
259 # know when to cleanup system resources that wxWidgets is holding. When
260 # the sys module is unloaded, the refcount on sys.__wxPythonCleanup
261 # goes to zero and it calls the wx.App_CleanUp function.
262
263 class __wxPyCleanup:
264 def __init__(self):
265 self.cleanup = _core_.App_CleanUp
266 def __del__(self):
267 self.cleanup()
268
269 _sys.__wxPythonCleanup = __wxPyCleanup()
270
271 ## # another possible solution, but it gets called too early...
272 ## import atexit
273 ## atexit.register(_core_.wxApp_CleanUp)
274
275
276 #----------------------------------------------------------------------------