]> git.saurik.com Git - wxWidgets.git/blob - wxPython/src/_app_ex.py
Allow overriding ApplyParentThemeBackground
[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 main application class. Derive from this and implement an OnInit
71 method that creates a frame and then calls self.SetTopWindow(frame)
72 """
73 outputWindowClass = PyOnDemandOutputWindow
74
75 def __init__(self, redirect=_defRedirect, filename=None, useBestVisual=False):
76 wx.PyApp.__init__(self)
77
78 if wx.Platform == "__WXMAC__":
79 try:
80 import MacOS
81 if not MacOS.WMAvailable():
82 print """\
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
85 your Mac."""
86 _sys.exit(1)
87 except:
88 pass
89
90 # This has to be done before OnInit
91 self.SetUseBestVisual(useBestVisual)
92
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.)
99 try:
100 import signal
101 signal.signal(signal.SIGINT, signal.SIG_DFL)
102 except:
103 pass
104
105 # Save and redirect the stdio to a window?
106 self.stdioWin = None
107 self.saveStdio = (_sys.stdout, _sys.stderr)
108 if redirect:
109 self.RedirectStdio(filename)
110
111 # This finishes the initialization of wxWindows and then calls
112 # the OnInit that should be present in the derived class
113 self._BootstrapApp()
114
115
116 def __del__(self):
117 try:
118 self.RestoreStdio() # Just in case the MainLoop was overridden
119 except:
120 pass
121
122
123 def SetTopWindow(self, frame):
124 """Set the \"main\" top level window"""
125 if self.stdioWin:
126 self.stdioWin.SetParent(frame)
127 wx.PyApp.SetTopWindow(self, frame)
128
129
130 def MainLoop(self):
131 """Execute the main GUI event loop"""
132 wx.PyApp.MainLoop(self)
133 self.RestoreStdio()
134
135
136 def RedirectStdio(self, filename=None):
137 """Redirect sys.stdout and sys.stderr to a file or a popup window."""
138 if filename:
139 _sys.stdout = _sys.stderr = open(filename, 'a')
140 else:
141 self.stdioWin = self.outputWindowClass()
142 _sys.stdout = _sys.stderr = self.stdioWin
143
144
145 def RestoreStdio(self):
146 _sys.stdout, _sys.stderr = self.saveStdio
147
148
149
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
162
163 #----------------------------------------------------------------------------
164
165 class PySimpleApp(wx.App):
166 """
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
169 about OnInit."""
170
171 def __init__(self, redirect=False, filename=None, useBestVisual=False):
172 wx.App.__init__(self, redirect, filename, useBestVisual)
173
174 def OnInit(self):
175 wx.InitAllImageHandlers()
176 return True
177
178
179 # Is anybody using this one?
180 class PyWidgetTester(wx.App):
181 def __init__(self, size = (250, 100)):
182 self.size = size
183 wx.App.__init__(self, 0)
184
185 def OnInit(self):
186 self.frame = wx.Frame(None, -1, "Widget Tester", pos=(0,0), size=self.size)
187 self.SetTopWindow(self.frame)
188 return True
189
190 def SetWidget(self, widgetClass, *args):
191 w = widgetClass(self.frame, *args)
192 self.frame.Show(True)
193
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.
199
200 class __wxPyCleanup:
201 def __init__(self):
202 self.cleanup = _core.App_CleanUp
203 def __del__(self):
204 self.cleanup()
205
206 _sys.__wxPythonCleanup = __wxPyCleanup()
207
208 ## # another possible solution, but it gets called too early...
209 ## if sys.version[0] == '2':
210 ## import atexit
211 ## atexit.register(_core.wxApp_CleanUp)
212 ## else:
213 ## sys.exitfunc = _core.wxApp_CleanUp
214
215
216 #----------------------------------------------------------------------------