]> git.saurik.com Git - wxWidgets.git/blame - wxPython/src/_app_ex.py
In GSocket_Destroy reorder GUI_Destroy and Shutdown when compiling for Darwin.
[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)
6c3b4aae
RD
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):
1e0c8722 121 """Set the \"main\" top level window"""
d14a1e28
RD
122 if self.stdioWin:
123 self.stdioWin.SetParent(frame)
124 wx.PyApp.SetTopWindow(self, frame)
125
126
127 def MainLoop(self):
1e0c8722 128 """Execute the main GUI event loop"""
d14a1e28
RD
129 wx.PyApp.MainLoop(self)
130 self.RestoreStdio()
131
132
133 def RedirectStdio(self, filename):
1e0c8722 134 """Redirect sys.stdout and sys.stderr to a file or a popup window."""
d14a1e28
RD
135 if filename:
136 _sys.stdout = _sys.stderr = open(filename, 'a')
137 else:
138 self.stdioWin = self.outputWindowClass()
139 _sys.stdout = _sys.stderr = self.stdioWin
140
141
142 def RestoreStdio(self):
143 _sys.stdout, _sys.stderr = self.saveStdio
144
145
146
147# change from wxPyApp_ to wxApp_
148App_GetMacSupportPCMenuShortcuts = _core.PyApp_GetMacSupportPCMenuShortcuts
149App_GetMacAboutMenuItemId = _core.PyApp_GetMacAboutMenuItemId
150App_GetMacPreferencesMenuItemId = _core.PyApp_GetMacPreferencesMenuItemId
151App_GetMacExitMenuItemId = _core.PyApp_GetMacExitMenuItemId
152App_GetMacHelpMenuTitleName = _core.PyApp_GetMacHelpMenuTitleName
153App_SetMacSupportPCMenuShortcuts = _core.PyApp_SetMacSupportPCMenuShortcuts
154App_SetMacAboutMenuItemId = _core.PyApp_SetMacAboutMenuItemId
155App_SetMacPreferencesMenuItemId = _core.PyApp_SetMacPreferencesMenuItemId
156App_SetMacExitMenuItemId = _core.PyApp_SetMacExitMenuItemId
157App_SetMacHelpMenuTitleName = _core.PyApp_SetMacHelpMenuTitleName
158App_GetComCtl32Version = _core.PyApp_GetComCtl32Version
159
160#----------------------------------------------------------------------------
161
162class PySimpleApp(wx.App):
6c3b4aae
RD
163 """
164 A simple application class. You can just create one of these and
165 then then make your top level windows later, and not have to worry
166 about OnInit."""
167
168 def __init__(self, redirect=False, filename=None, useBestVisual=False):
169 wx.App.__init__(self, redirect, filename, useBestVisual)
170
d14a1e28
RD
171 def OnInit(self):
172 wx.InitAllImageHandlers()
173 return True
174
175
6c3b4aae 176# Is anybody using this one?
d14a1e28
RD
177class PyWidgetTester(wx.App):
178 def __init__(self, size = (250, 100)):
179 self.size = size
180 wx.App.__init__(self, 0)
181
182 def OnInit(self):
64e8a1f0 183 self.frame = wx.Frame(None, -1, "Widget Tester", pos=(0,0), size=self.size)
d14a1e28
RD
184 self.SetTopWindow(self.frame)
185 return True
186
187 def SetWidget(self, widgetClass, *args):
188 w = widgetClass(self.frame, *args)
189 self.frame.Show(True)
190
191#----------------------------------------------------------------------------
192# DO NOT hold any other references to this object. This is how we
193# know when to cleanup system resources that wxWin is holding. When
194# the sys module is unloaded, the refcount on sys.__wxPythonCleanup
195# goes to zero and it calls the wxApp_CleanUp function.
196
197class __wxPyCleanup:
198 def __init__(self):
199 self.cleanup = _core.App_CleanUp
200 def __del__(self):
201 self.cleanup()
202
203_sys.__wxPythonCleanup = __wxPyCleanup()
204
205## # another possible solution, but it gets called too early...
206## if sys.version[0] == '2':
207## import atexit
208## atexit.register(_core.wxApp_CleanUp)
209## else:
210## sys.exitfunc = _core.wxApp_CleanUp
211
212
213#----------------------------------------------------------------------------