~ubuntu-dev/wxwidgets2.6/upstream-debian

« back to all changes in this revision

Viewing changes to wxPython/src/_app_ex.py

  • Committer: Daniel T Chen
  • Date: 2006-06-26 10:15:11 UTC
  • Revision ID: crimsun@ubuntu.com-20060626101511-a4436cec4c6d9b35
ImportĀ DebianĀ 2.6.3.2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.pos    = wx.DefaultPosition
 
15
        self.size   = (450, 300)
 
16
        self.parent = None
 
17
 
 
18
    def SetParent(self, parent):
 
19
        """Set the window to be used as the popup Frame's parent."""
 
20
        self.parent = parent
 
21
 
 
22
 
 
23
    def CreateOutputWindow(self, st):
 
24
        self.frame = wx.Frame(self.parent, -1, self.title, self.pos, self.size,
 
25
                              style=wx.DEFAULT_FRAME_STYLE)
 
26
        self.text  = wx.TextCtrl(self.frame, -1, "",
 
27
                                 style=wx.TE_MULTILINE|wx.TE_READONLY)
 
28
        self.text.AppendText(st)
 
29
        self.frame.Show(True)
 
30
        EVT_CLOSE(self.frame, self.OnCloseWindow)
 
31
        
 
32
 
 
33
    def OnCloseWindow(self, event):
 
34
        if self.frame is not None:
 
35
            self.frame.Destroy()
 
36
        self.frame = None
 
37
        self.text  = None
 
38
 
 
39
 
 
40
    # These methods provide the file-like output behaviour.
 
41
    def write(self, text):
 
42
        """
 
43
        Create the output window if needed and write the string to it.
 
44
        If not called in the context of the gui thread then uses
 
45
        CallAfter to do the work there.
 
46
        """        
 
47
        if self.frame is None:
 
48
            if not wx.Thread_IsMain():
 
49
                wx.CallAfter(self.CreateOutputWindow, text)
 
50
            else:
 
51
                self.CreateOutputWindow(text)
 
52
        else:
 
53
            if not wx.Thread_IsMain():
 
54
                wx.CallAfter(self.text.AppendText, text)
 
55
            else:
 
56
                self.text.AppendText(text)
 
57
 
 
58
 
 
59
    def close(self):
 
60
        if self.frame is not None:
 
61
            wx.CallAfter(self.frame.Close)
 
62
 
 
63
 
 
64
    def flush(self):
 
65
        pass
 
66
    
 
67
 
 
68
 
 
69
#----------------------------------------------------------------------
 
70
 
 
71
_defRedirect = (wx.Platform == '__WXMSW__' or wx.Platform == '__WXMAC__')
 
72
 
 
73
class App(wx.PyApp):
 
74
    """
 
75
    The ``wx.App`` class represents the application and is used to:
 
76
 
 
77
      * bootstrap the wxPython system and initialize the underlying
 
78
        gui toolkit
 
79
      * set and get application-wide properties
 
80
      * implement the windowing system main message or event loop,
 
81
        and to dispatch events to window instances
 
82
      * etc.
 
83
 
 
84
    Every application must have a ``wx.App`` instance, and all
 
85
    creation of UI objects should be delayed until after the
 
86
    ``wx.App`` object has been created in order to ensure that the gui
 
87
    platform and wxWidgets have been fully initialized.
 
88
 
 
89
    Normally you would derive from this class and implement an
 
90
    ``OnInit`` method that creates a frame and then calls
 
91
    ``self.SetTopWindow(frame)``.
 
92
 
 
93
    :see: `wx.PySimpleApp` for a simpler app class that can be used
 
94
           directly.
 
95
    """
 
96
    
 
97
    outputWindowClass = PyOnDemandOutputWindow
 
98
 
 
99
    def __init__(self, redirect=_defRedirect, filename=None,
 
100
                 useBestVisual=False, clearSigInt=True):
 
101
        """
 
102
        Construct a ``wx.App`` object.  
 
103
 
 
104
        :param redirect: Should ``sys.stdout`` and ``sys.stderr`` be
 
105
            redirected?  Defaults to True on Windows and Mac, False
 
106
            otherwise.  If `filename` is None then output will be
 
107
            redirected to a window that pops up as needed.  (You can
 
108
            control what kind of window is created for the output by
 
109
            resetting the class variable ``outputWindowClass`` to a
 
110
            class of your choosing.)
 
111
 
 
112
        :param filename: The name of a file to redirect output to, if
 
113
            redirect is True.
 
114
 
 
115
        :param useBestVisual: Should the app try to use the best
 
116
            available visual provided by the system (only relevant on
 
117
            systems that have more than one visual.)  This parameter
 
118
            must be used instead of calling `SetUseBestVisual` later
 
119
            on because it must be set before the underlying GUI
 
120
            toolkit is initialized.
 
121
 
 
122
        :param clearSigInt: Should SIGINT be cleared?  This allows the
 
123
            app to terminate upon a Ctrl-C in the console like other
 
124
            GUI apps will.
 
125
 
 
126
        :note: You should override OnInit to do applicaition
 
127
            initialization to ensure that the system, toolkit and
 
128
            wxWidgets are fully initialized.
 
129
        """
 
130
        wx.PyApp.__init__(self)
 
131
 
 
132
        if wx.Platform == "__WXMAC__":
 
133
            try:
 
134
                import MacOS
 
135
                if not MacOS.WMAvailable():
 
136
                    print """\
 
137
This program needs access to the screen. Please run with 'pythonw',
 
138
not 'python', and only when you are logged in on the main display of
 
139
your Mac."""
 
140
                    _sys.exit(1)
 
141
            except SystemExit:
 
142
                raise
 
143
            except:
 
144
                pass
 
145
 
 
146
        # This has to be done before OnInit
 
147
        self.SetUseBestVisual(useBestVisual)
 
148
 
 
149
        # Set the default handler for SIGINT.  This fixes a problem
 
150
        # where if Ctrl-C is pressed in the console that started this
 
151
        # app then it will not appear to do anything, (not even send
 
152
        # KeyboardInterrupt???)  but will later segfault on exit.  By
 
153
        # setting the default handler then the app will exit, as
 
154
        # expected (depending on platform.)
 
155
        if clearSigInt:
 
156
            try:
 
157
                import signal
 
158
                signal.signal(signal.SIGINT, signal.SIG_DFL)
 
159
            except:
 
160
                pass
 
161
 
 
162
        # Save and redirect the stdio to a window?
 
163
        self.stdioWin = None
 
164
        self.saveStdio = (_sys.stdout, _sys.stderr)
 
165
        if redirect:
 
166
            self.RedirectStdio(filename)
 
167
 
 
168
        # Use Python's install prefix as the default  
 
169
        wx.StandardPaths.Get().SetInstallPrefix(_sys.prefix)
 
170
 
 
171
        # This finishes the initialization of wxWindows and then calls
 
172
        # the OnInit that should be present in the derived class
 
173
        self._BootstrapApp()
 
174
 
 
175
 
 
176
    def __del__(self, destroy=wx.PyApp.__del__):
 
177
        self.RestoreStdio()  # Just in case the MainLoop was overridden
 
178
        destroy(self)
 
179
 
 
180
    def Destroy(self):
 
181
        wx.PyApp.Destroy(self)
 
182
        self.thisown = 0
 
183
 
 
184
    def SetTopWindow(self, frame):
 
185
        """Set the \"main\" top level window"""
 
186
        if self.stdioWin:
 
187
            self.stdioWin.SetParent(frame)
 
188
        wx.PyApp.SetTopWindow(self, frame)
 
189
 
 
190
 
 
191
    def MainLoop(self):
 
192
        """Execute the main GUI event loop"""
 
193
        wx.PyApp.MainLoop(self)
 
194
        self.RestoreStdio()
 
195
 
 
196
 
 
197
    def RedirectStdio(self, filename=None):
 
198
        """Redirect sys.stdout and sys.stderr to a file or a popup window."""
 
199
        if filename:
 
200
            _sys.stdout = _sys.stderr = open(filename, 'a')
 
201
        else:
 
202
            self.stdioWin = self.outputWindowClass()
 
203
            _sys.stdout = _sys.stderr = self.stdioWin
 
204
 
 
205
 
 
206
    def RestoreStdio(self):
 
207
        try:
 
208
            _sys.stdout, _sys.stderr = self.saveStdio
 
209
        except:
 
210
            pass
 
211
 
 
212
 
 
213
    def SetOutputWindowAttributes(self, title=None, pos=None, size=None):
 
214
        """
 
215
        Set the title, position and/or size of the output window if
 
216
        the stdio has been redirected.  This should be called before
 
217
        any output would cause the output window to be created.
 
218
        """
 
219
        if self.stdioWin:
 
220
            if title is not None:
 
221
                self.stdioWin.title = title
 
222
            if pos is not None:
 
223
                self.stdioWin.pos = pos
 
224
            if size is not None:
 
225
                self.stdioWin.size = size
 
226
            
 
227
 
 
228
 
 
229
 
 
230
# change from wx.PyApp_XX to wx.App_XX
 
231
App_GetMacSupportPCMenuShortcuts = _core_.PyApp_GetMacSupportPCMenuShortcuts
 
232
App_GetMacAboutMenuItemId        = _core_.PyApp_GetMacAboutMenuItemId
 
233
App_GetMacPreferencesMenuItemId  = _core_.PyApp_GetMacPreferencesMenuItemId
 
234
App_GetMacExitMenuItemId         = _core_.PyApp_GetMacExitMenuItemId
 
235
App_GetMacHelpMenuTitleName      = _core_.PyApp_GetMacHelpMenuTitleName
 
236
App_SetMacSupportPCMenuShortcuts = _core_.PyApp_SetMacSupportPCMenuShortcuts
 
237
App_SetMacAboutMenuItemId        = _core_.PyApp_SetMacAboutMenuItemId
 
238
App_SetMacPreferencesMenuItemId  = _core_.PyApp_SetMacPreferencesMenuItemId
 
239
App_SetMacExitMenuItemId         = _core_.PyApp_SetMacExitMenuItemId
 
240
App_SetMacHelpMenuTitleName      = _core_.PyApp_SetMacHelpMenuTitleName
 
241
App_GetComCtl32Version           = _core_.PyApp_GetComCtl32Version
 
242
 
 
243
#----------------------------------------------------------------------------
 
244
 
 
245
class PySimpleApp(wx.App):
 
246
    """
 
247
    A simple application class.  You can just create one of these and
 
248
    then then make your top level windows later, and not have to worry
 
249
    about OnInit.  For example::
 
250
 
 
251
        app = wx.PySimpleApp()
 
252
        frame = wx.Frame(None, title='Hello World')
 
253
        frame.Show()
 
254
        app.MainLoop()
 
255
 
 
256
    :see: `wx.App` 
 
257
    """
 
258
 
 
259
    def __init__(self, redirect=False, filename=None,
 
260
                 useBestVisual=False, clearSigInt=True):
 
261
        """
 
262
        :see: `wx.App.__init__`
 
263
        """
 
264
        wx.App.__init__(self, redirect, filename, useBestVisual, clearSigInt)
 
265
        
 
266
    def OnInit(self):
 
267
        return True
 
268
 
 
269
 
 
270
 
 
271
# Is anybody using this one?
 
272
class PyWidgetTester(wx.App):
 
273
    def __init__(self, size = (250, 100)):
 
274
        self.size = size
 
275
        wx.App.__init__(self, 0)
 
276
 
 
277
    def OnInit(self):
 
278
        self.frame = wx.Frame(None, -1, "Widget Tester", pos=(0,0), size=self.size)
 
279
        self.SetTopWindow(self.frame)
 
280
        return True
 
281
 
 
282
    def SetWidget(self, widgetClass, *args, **kwargs):
 
283
        w = widgetClass(self.frame, *args, **kwargs)
 
284
        self.frame.Show(True)
 
285
 
 
286
#----------------------------------------------------------------------------
 
287
# DO NOT hold any other references to this object.  This is how we
 
288
# know when to cleanup system resources that wxWidgets is holding.  When
 
289
# the sys module is unloaded, the refcount on sys.__wxPythonCleanup
 
290
# goes to zero and it calls the wx.App_CleanUp function.
 
291
 
 
292
class __wxPyCleanup:
 
293
    def __init__(self):
 
294
        self.cleanup = _core_.App_CleanUp
 
295
    def __del__(self):
 
296
        self.cleanup()
 
297
 
 
298
_sys.__wxPythonCleanup = __wxPyCleanup()
 
299
 
 
300
## # another possible solution, but it gets called too early...
 
301
## import atexit
 
302
## atexit.register(_core_.wxApp_CleanUp)
 
303
 
 
304
 
 
305
#----------------------------------------------------------------------------