]> git.saurik.com Git - wxWidgets.git/blame - wxPython/src/_app_ex.py
Lots of little bug fixes, API updates, etc.
[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)
24 self.text = wxTextCtrl(self.frame, -1, "",
25 style = wx.TE_MULTILINE | wx.TE_READONLY)
26 self.frame.SetSize((450, 300))
27 self.frame.Show(True)
28 EVT_CLOSE(self.frame, self.OnCloseWindow)
29
d14a1e28
RD
30
31 # These methods provide the file-like output behaviour.
6c3b4aae
RD
32 def write(self, text):
33 """
34 Create the output window if needed and write the string to it.
35 If not called in the context of the gui thread then uses
36 CallAfter to do the work there.
37 """
38 if self.frame is None:
39 if not wx.Thread_IsMain():
40 wx.CallAfter(self.CreateOutputWindow, text)
41 else:
42 self.CreateOutputWindow(text)
43 else:
44 if not wx.Thread_IsMain():
45 wx.CallAfter(self.text.AppendText, text)
46 else:
47 self.text.AppendText(text)
48
d14a1e28
RD
49
50 def close(self):
6c3b4aae
RD
51 if self.frame is not None:
52 wx.CallAfter(self.frame.Close)
d14a1e28
RD
53
54
6c3b4aae
RD
55 def OnCloseWindow(self, event):
56 if self.frame is not None:
57 self.frame.Destroy()
58 self.frame = None
59 self.text = None
60
d14a1e28 61#----------------------------------------------------------------------
d14a1e28
RD
62
63_defRedirect = (wx.Platform == '__WXMSW__' or wx.Platform == '__WXMAC__')
64
65class App(wx.PyApp):
6c3b4aae
RD
66 """
67 The main application class. Derive from this and implement an OnInit
68 method that creates a frame and then calls self.SetTopWindow(frame)
69 """
d14a1e28
RD
70 outputWindowClass = PyOnDemandOutputWindow
71
72 def __init__(self, redirect=_defRedirect, filename=None, useBestVisual=False):
73 wx.PyApp.__init__(self)
74
75 if wx.Platform == "__WXMAC__":
76 try:
77 import MacOS
78 if not MacOS.WMAvailable():
79 print """\
80This program needs access to the screen. Please run with 'pythonw',
81not 'python', and only when you are logged in on the main display of
82your Mac."""
83 _sys.exit(1)
84 except:
85 pass
86
87 # This has to be done before OnInit
88 self.SetUseBestVisual(useBestVisual)
89
90 # Set the default handler for SIGINT. This fixes a problem
91 # where if Ctrl-C is pressed in the console that started this
92 # app then it will not appear to do anything, (not even send
93 # KeyboardInterrupt???) but will later segfault on exit. By
94 # setting the default handler then the app will exit, as
95 # expected (depending on platform.)
96 try:
97 import signal
98 signal.signal(signal.SIGINT, signal.SIG_DFL)
99 except:
100 pass
101
102 # Save and redirect the stdio to a window?
103 self.stdioWin = None
104 self.saveStdio = (_sys.stdout, _sys.stderr)
105 if redirect:
106 self.RedirectStdio(filename)
107
108 # This finishes the initialization of wxWindows and then calls
109 # the OnInit that should be present in the derived class
110 self._BootstrapApp()
111
112
113 def __del__(self):
114 try:
115 self.RestoreStdio() # Just in case the MainLoop was overridden
116 except:
117 pass
118
119
120 def SetTopWindow(self, frame):
121 if self.stdioWin:
122 self.stdioWin.SetParent(frame)
123 wx.PyApp.SetTopWindow(self, frame)
124
125
126 def MainLoop(self):
127 wx.PyApp.MainLoop(self)
128 self.RestoreStdio()
129
130
131 def RedirectStdio(self, filename):
132 if filename:
133 _sys.stdout = _sys.stderr = open(filename, 'a')
134 else:
135 self.stdioWin = self.outputWindowClass()
136 _sys.stdout = _sys.stderr = self.stdioWin
137
138
139 def RestoreStdio(self):
140 _sys.stdout, _sys.stderr = self.saveStdio
141
142
143
144# change from wxPyApp_ to wxApp_
145App_GetMacSupportPCMenuShortcuts = _core.PyApp_GetMacSupportPCMenuShortcuts
146App_GetMacAboutMenuItemId = _core.PyApp_GetMacAboutMenuItemId
147App_GetMacPreferencesMenuItemId = _core.PyApp_GetMacPreferencesMenuItemId
148App_GetMacExitMenuItemId = _core.PyApp_GetMacExitMenuItemId
149App_GetMacHelpMenuTitleName = _core.PyApp_GetMacHelpMenuTitleName
150App_SetMacSupportPCMenuShortcuts = _core.PyApp_SetMacSupportPCMenuShortcuts
151App_SetMacAboutMenuItemId = _core.PyApp_SetMacAboutMenuItemId
152App_SetMacPreferencesMenuItemId = _core.PyApp_SetMacPreferencesMenuItemId
153App_SetMacExitMenuItemId = _core.PyApp_SetMacExitMenuItemId
154App_SetMacHelpMenuTitleName = _core.PyApp_SetMacHelpMenuTitleName
155App_GetComCtl32Version = _core.PyApp_GetComCtl32Version
156
157#----------------------------------------------------------------------------
158
159class PySimpleApp(wx.App):
6c3b4aae
RD
160 """
161 A simple application class. You can just create one of these and
162 then then make your top level windows later, and not have to worry
163 about OnInit."""
164
165 def __init__(self, redirect=False, filename=None, useBestVisual=False):
166 wx.App.__init__(self, redirect, filename, useBestVisual)
167
d14a1e28
RD
168 def OnInit(self):
169 wx.InitAllImageHandlers()
170 return True
171
172
6c3b4aae 173# Is anybody using this one?
d14a1e28
RD
174class PyWidgetTester(wx.App):
175 def __init__(self, size = (250, 100)):
176 self.size = size
177 wx.App.__init__(self, 0)
178
179 def OnInit(self):
180 self.frame = wxFrame(None, -1, "Widget Tester", pos=(0,0), size=self.size)
181 self.SetTopWindow(self.frame)
182 return True
183
184 def SetWidget(self, widgetClass, *args):
185 w = widgetClass(self.frame, *args)
186 self.frame.Show(True)
187
188#----------------------------------------------------------------------------
189# DO NOT hold any other references to this object. This is how we
190# know when to cleanup system resources that wxWin is holding. When
191# the sys module is unloaded, the refcount on sys.__wxPythonCleanup
192# goes to zero and it calls the wxApp_CleanUp function.
193
194class __wxPyCleanup:
195 def __init__(self):
196 self.cleanup = _core.App_CleanUp
197 def __del__(self):
198 self.cleanup()
199
200_sys.__wxPythonCleanup = __wxPyCleanup()
201
202## # another possible solution, but it gets called too early...
203## if sys.version[0] == '2':
204## import atexit
205## atexit.register(_core.wxApp_CleanUp)
206## else:
207## sys.exitfunc = _core.wxApp_CleanUp
208
209
210#----------------------------------------------------------------------------