Redirecting output

If wxPython is controlling the standard streams, then text sent to the streams via any mechanism—including a print statement or a system traceback—is redirected to a separate wxPython frame. Text sent to the streams before the wxPython application begins or after it ends is, of course, processed normally. Listing 2.1, demonstrates both the application lifecycle and the stdout/stderr redirection.

Listing 2.1 A sample startup script showing output stream redirection

#!/usr/bin/env python import wx import sys class Frame(wx.Frame):

class App(wx.App)

def _init_(self, redirect=True, filename=None):

print "App _init_"

wx.App._init_(self, redirect, filename)

def Onlnit(self):

print "Onlnit" <— Writing to stdout self.frame = Frame(parent=None, id=-1, title='Startup') <1— Creating self.frame.Show() the frame self.SetTopWindow(self.frame)

print >> sys.stderr, "A pretend error message" <1— Writing to stderr return True def OnExit(self): print "OnExit"

app = App(redirect=True) Q Text redirection starts here print "before MainLoop"

app.MainLoop() C The main event loop is entered here print "after MainLoop"

Q This line creates the application object. After this line, all text sent to stderr or stdout can be redirected to a frame by wxPython. The arguments to the constructor determine whether this redirection takes place. C When run, this application creates a blank frame, and also generates a frame with the redirected output, as shown in figure 2.3. Notice also that both stdout and stderr messages get directed to the window.

After you run this program you'll see that your console has the following output:

App _init_

after MainLoop

The first line is generated before the frames are opened, the second line is generated after they close.

By looking at both the console and the output frame, we can trace the application lifecycle.

The first bubble in figure 2.2—Start Script—corresponds to the first lines run from the script's_main_clause. The transition to the next bubble comes immediately in the line marked Q. The instantiation of the instance calls the method

Figure 2.3 The stdout/stderr window created by Listing 2.1

Figure 2.3 The stdout/stderr window created by Listing 2.1

wx.App._init_(). Then control goes to OnInit(), which is automatically called by wxPython. From there, the program jumps to the wx.Frame.__init__(), which is run when the wx.Frame instance is instantiated. Finally, control winds back to the _main_ clause, where MainLoop() is invoked, corresponding to the third bubble in figure 2.2. After the main loop ends, then wx.App.OnExit() is called by wxPython, transitioning to the fourth bubble, and then the rest of the script finishes out the process.

"Wait a minute," you say, "the message from OnExit() didn't display in either the window or the console." As we'll see, the message does display in the wxPython frame, but it does so right before the window is closed, so that it's nearly impossible to capture in a screen shot.

The quickly vanishing OnExit() message is a symptom of a larger issue with the output frame. Although it's a useful feature during development, you don't necessarily want the error stream frame popping out in a user's face at run time. Furthermore, if an error condition happens during the OnInit() method, it gets sent to the output frame, but the error causes the application to exit, since OnInit() will return a False value in case of an error condition. The result is that the line of text is displayed but disappears far too quickly to be seen.

Was this article helpful?

0 0

Post a comment