00001
00002
00003
00004 class PyOnDemandOutputWindow:
00005 """
00006 A class that can be used for redirecting Python's stdout and
00007 stderr streams. It will do nothing until something is wrriten to
00008 the stream at which point it will create a Frame with a text area
00009 and write the text there.
00010 """
00011 def __init__(self, title = "wxPython: stdout/stderr"):
00012 self.frame = None
00013 self.title = title
00014 self.pos = wx.DefaultPosition
00015 self.size = (450, 300)
00016 self.parent = None
00017
00018 def SetParent(self, parent):
00019 """Set the window to be used as the popup Frame's parent."""
00020 self.parent = parent
00021
00022
00023 def CreateOutputWindow(self, st):
00024 self.frame = wx.Frame(self.parent, -1, self.title, self.pos, self.size,
00025 style=wx.DEFAULT_FRAME_STYLE)
00026 self.text = wx.TextCtrl(self.frame, -1, "",
00027 style=wx.TE_MULTILINE|wx.TE_READONLY)
00028 self.text.AppendText(st)
00029 self.frame.Show(True)
00030 self.frame.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
00031
00032
00033 def OnCloseWindow(self, event):
00034 if self.frame is not None:
00035 self.frame.Destroy()
00036 self.frame = None
00037 self.text = None
00038
00039
00040
00041 def write(self, text):
00042 """
00043 Create the output window if needed and write the string to it.
00044 If not called in the context of the gui thread then uses
00045 CallAfter to do the work there.
00046 """
00047 if self.frame is None:
00048 if not wx.Thread_IsMain():
00049 wx.CallAfter(self.CreateOutputWindow, text)
00050 else:
00051 self.CreateOutputWindow(text)
00052 else:
00053 if not wx.Thread_IsMain():
00054 wx.CallAfter(self.text.AppendText, text)
00055 else:
00056 self.text.AppendText(text)
00057
00058
00059 def close(self):
00060 if self.frame is not None:
00061 wx.CallAfter(self.frame.Close)
00062
00063
00064 def flush(self):
00065 pass
00066
00067
00068
00069
00070
00071 _defRedirect = (wx.Platform == '__WXMSW__' or wx.Platform == '__WXMAC__')
00072
00073 class App(wx.PyApp):
00074 """
00075 The ``wx.App`` class represents the application and is used to:
00076
00077 * bootstrap the wxPython system and initialize the underlying
00078 gui toolkit
00079 * set and get application-wide properties
00080 * implement the windowing system main message or event loop,
00081 and to dispatch events to window instances
00082 * etc.
00083
00084 Every application must have a ``wx.App`` instance, and all
00085 creation of UI objects should be delayed until after the
00086 ``wx.App`` object has been created in order to ensure that the gui
00087 platform and wxWidgets have been fully initialized.
00088
00089 Normally you would derive from this class and implement an
00090 ``OnInit`` method that creates a frame and then calls
00091 ``self.SetTopWindow(frame)``.
00092
00093 :see: `wx.PySimpleApp` for a simpler app class that can be used
00094 directly.
00095 """
00096
00097 outputWindowClass = PyOnDemandOutputWindow
00098
00099 def __init__(self, redirect=_defRedirect, filename=None,
00100 useBestVisual=False, clearSigInt=True):
00101 """
00102 Construct a ``wx.App`` object.
00103
00104 :param redirect: Should ``sys.stdout`` and ``sys.stderr`` be
00105 redirected? Defaults to True on Windows and Mac, False
00106 otherwise. If `filename` is None then output will be
00107 redirected to a window that pops up as needed. (You can
00108 control what kind of window is created for the output by
00109 resetting the class variable ``outputWindowClass`` to a
00110 class of your choosing.)
00111
00112 :param filename: The name of a file to redirect output to, if
00113 redirect is True.
00114
00115 :param useBestVisual: Should the app try to use the best
00116 available visual provided by the system (only relevant on
00117 systems that have more than one visual.) This parameter
00118 must be used instead of calling `SetUseBestVisual` later
00119 on because it must be set before the underlying GUI
00120 toolkit is initialized.
00121
00122 :param clearSigInt: Should SIGINT be cleared? This allows the
00123 app to terminate upon a Ctrl-C in the console like other
00124 GUI apps will.
00125
00126 :note: You should override OnInit to do applicaition
00127 initialization to ensure that the system, toolkit and
00128 wxWidgets are fully initialized.
00129 """
00130
00131 wx.PyApp.__init__(self)
00132
00133
00134 if not self.IsDisplayAvailable():
00135
00136 if wx.Platform == "__WXMAC__":
00137 msg = """This program needs access to the screen.
00138 Please run with 'pythonw', not 'python', and only when you are logged
00139 in on the main display of your Mac."""
00140
00141 elif wx.Platform == "__WXGTK__":
00142 msg ="Unable to access the X Display, is $DISPLAY set properly?"
00143
00144 else:
00145 msg = "Unable to create GUI"
00146
00147
00148 raise SystemExit(msg)
00149
00150
00151 self.SetUseBestVisual(useBestVisual)
00152
00153
00154
00155
00156
00157
00158
00159 if clearSigInt:
00160 try:
00161 import signal
00162 signal.signal(signal.SIGINT, signal.SIG_DFL)
00163 except:
00164 pass
00165
00166
00167 self.stdioWin = None
00168 self.saveStdio = (_sys.stdout, _sys.stderr)
00169 if redirect:
00170 self.RedirectStdio(filename)
00171
00172
00173 wx.StandardPaths.Get().SetInstallPrefix(_sys.prefix)
00174
00175
00176 wx.SystemOptions.SetOptionInt("mac.listctrl.always_use_generic", 1)
00177
00178
00179
00180 self._BootstrapApp()
00181
00182
00183 def OnPreInit(self):
00184 """
00185 Things that must be done after _BootstrapApp has done its
00186 thing, but would be nice if they were already done by the time
00187 that OnInit is called.
00188 """
00189 wx.StockGDI._initStockObjects()
00190
00191
00192 def __del__(self, destroy=wx.PyApp.__del__):
00193 self.RestoreStdio()
00194 destroy(self)
00195
00196 def Destroy(self):
00197 self.this.own(False)
00198 wx.PyApp.Destroy(self)
00199
00200 def SetTopWindow(self, frame):
00201 """Set the \"main\" top level window"""
00202 if self.stdioWin:
00203 self.stdioWin.SetParent(frame)
00204 wx.PyApp.SetTopWindow(self, frame)
00205
00206
00207 def MainLoop(self):
00208 """Execute the main GUI event loop"""
00209 wx.PyApp.MainLoop(self)
00210 self.RestoreStdio()
00211
00212
00213 def RedirectStdio(self, filename=None):
00214 """Redirect sys.stdout and sys.stderr to a file or a popup window."""
00215 if filename:
00216 _sys.stdout = _sys.stderr = open(filename, 'a')
00217 else:
00218 self.stdioWin = self.outputWindowClass()
00219 _sys.stdout = _sys.stderr = self.stdioWin
00220
00221
00222 def RestoreStdio(self):
00223 try:
00224 _sys.stdout, _sys.stderr = self.saveStdio
00225 except:
00226 pass
00227
00228
00229 def SetOutputWindowAttributes(self, title=None, pos=None, size=None):
00230 """
00231 Set the title, position and/or size of the output window if
00232 the stdio has been redirected. This should be called before
00233 any output would cause the output window to be created.
00234 """
00235 if self.stdioWin:
00236 if title is not None:
00237 self.stdioWin.title = title
00238 if pos is not None:
00239 self.stdioWin.pos = pos
00240 if size is not None:
00241 self.stdioWin.size = size
00242
00243
00244
00245
00246
00247 App_GetMacSupportPCMenuShortcuts = _core_.PyApp_GetMacSupportPCMenuShortcuts
00248 App_GetMacAboutMenuItemId = _core_.PyApp_GetMacAboutMenuItemId
00249 App_GetMacPreferencesMenuItemId = _core_.PyApp_GetMacPreferencesMenuItemId
00250 App_GetMacExitMenuItemId = _core_.PyApp_GetMacExitMenuItemId
00251 App_GetMacHelpMenuTitleName = _core_.PyApp_GetMacHelpMenuTitleName
00252 App_SetMacSupportPCMenuShortcuts = _core_.PyApp_SetMacSupportPCMenuShortcuts
00253 App_SetMacAboutMenuItemId = _core_.PyApp_SetMacAboutMenuItemId
00254 App_SetMacPreferencesMenuItemId = _core_.PyApp_SetMacPreferencesMenuItemId
00255 App_SetMacExitMenuItemId = _core_.PyApp_SetMacExitMenuItemId
00256 App_SetMacHelpMenuTitleName = _core_.PyApp_SetMacHelpMenuTitleName
00257 App_GetComCtl32Version = _core_.PyApp_GetComCtl32Version
00258
00259
00260
00261 class PySimpleApp(wx.App):
00262 """
00263 A simple application class. You can just create one of these and
00264 then then make your top level windows later, and not have to worry
00265 about OnInit. For example::
00266
00267 app = wx.PySimpleApp()
00268 frame = wx.Frame(None, title='Hello World')
00269 frame.Show()
00270 app.MainLoop()
00271
00272 :see: `wx.App`
00273 """
00274
00275 def __init__(self, redirect=False, filename=None,
00276 useBestVisual=False, clearSigInt=True):
00277 """
00278 :see: `wx.App.__init__`
00279 """
00280 wx.App.__init__(self, redirect, filename, useBestVisual, clearSigInt)
00281
00282 def OnInit(self):
00283 return True
00284
00285
00286
00287
00288 class PyWidgetTester(wx.App):
00289 def __init__(self, size = (250, 100)):
00290 self.size = size
00291 wx.App.__init__(self, 0)
00292
00293 def OnInit(self):
00294 self.frame = wx.Frame(None, -1, "Widget Tester", pos=(0,0), size=self.size)
00295 self.SetTopWindow(self.frame)
00296 return True
00297
00298 def SetWidget(self, widgetClass, *args, **kwargs):
00299 w = widgetClass(self.frame, *args, **kwargs)
00300 self.frame.Show(True)
00301
00302
00303
00304
00305
00306
00307
00308 class __wxPyCleanup:
00309 def __init__(self):
00310 self.cleanup = _core_.App_CleanUp
00311 def __del__(self):
00312 self.cleanup()
00313
00314 _sys.__wxPythonCleanup = __wxPyCleanup()
00315
00316
00317
00318
00319
00320
00321