]> git.saurik.com Git - wxWidgets.git/blame - wxPython/src/_app_ex.py
wxToggleButton on wxMac has these methods now
[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
RD
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 """
d14a1e28
RD
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 """\
83This program needs access to the screen. Please run with 'pythonw',
84not 'python', and only when you are logged in on the main display of
85your 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):
1e0c8722 124 """Set the \"main\" top level window"""
d14a1e28
RD
125 if self.stdioWin:
126 self.stdioWin.SetParent(frame)
127 wx.PyApp.SetTopWindow(self, frame)
128
129
130 def MainLoop(self):
1e0c8722 131 """Execute the main GUI event loop"""
d14a1e28
RD
132 wx.PyApp.MainLoop(self)
133 self.RestoreStdio()
134
135
330af869 136 def RedirectStdio(self, filename=None):
1e0c8722 137 """Redirect sys.stdout and sys.stderr to a file or a popup window."""
d14a1e28
RD
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_
54f9ee45
RD
151App_GetMacSupportPCMenuShortcuts = _core_.PyApp_GetMacSupportPCMenuShortcuts
152App_GetMacAboutMenuItemId = _core_.PyApp_GetMacAboutMenuItemId
153App_GetMacPreferencesMenuItemId = _core_.PyApp_GetMacPreferencesMenuItemId
154App_GetMacExitMenuItemId = _core_.PyApp_GetMacExitMenuItemId
155App_GetMacHelpMenuTitleName = _core_.PyApp_GetMacHelpMenuTitleName
156App_SetMacSupportPCMenuShortcuts = _core_.PyApp_SetMacSupportPCMenuShortcuts
157App_SetMacAboutMenuItemId = _core_.PyApp_SetMacAboutMenuItemId
158App_SetMacPreferencesMenuItemId = _core_.PyApp_SetMacPreferencesMenuItemId
159App_SetMacExitMenuItemId = _core_.PyApp_SetMacExitMenuItemId
160App_SetMacHelpMenuTitleName = _core_.PyApp_SetMacHelpMenuTitleName
161App_GetComCtl32Version = _core_.PyApp_GetComCtl32Version
d14a1e28
RD
162
163#----------------------------------------------------------------------------
164
165class PySimpleApp(wx.App):
6c3b4aae
RD
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
d14a1e28
RD
174 def OnInit(self):
175 wx.InitAllImageHandlers()
176 return True
177
178
6c3b4aae 179# Is anybody using this one?
d14a1e28
RD
180class 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):
64e8a1f0 186 self.frame = wx.Frame(None, -1, "Widget Tester", pos=(0,0), size=self.size)
d14a1e28
RD
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
200class __wxPyCleanup:
201 def __init__(self):
54f9ee45 202 self.cleanup = _core_.App_CleanUp
d14a1e28
RD
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
54f9ee45 211## atexit.register(_core_.wxApp_CleanUp)
d14a1e28 212## else:
54f9ee45 213## sys.exitfunc = _core_.wxApp_CleanUp
d14a1e28
RD
214
215
216#----------------------------------------------------------------------------