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