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