[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1

Notice the -u Python command-line flag used here: it forces the spawned program’s
standard streams to be unbuffered, so we get printed text immediately as it is produced,
instead of waiting for the spawned program to completely finish.


We talked about this option in Chapter 5, when discussing deadlocks and pipes. Recall
that print writes to sys.stdout, which is normally buffered when connected to a pipe
this way. If we don’t use the -u flag here and the spawned program doesn’t manually
call sys.stdout.flush, we won’t see any output in the GUI until the spawned program
exits or until its buffers fill up. If the spawned program is a perpetual loop that does
not exit, we may be waiting a long time for output to appear on the pipe, and hence,
in the GUI.


This approach makes the non-GUI code in Example 10-27 much simpler: it just writes
to standard output as usual, and it need not be concerned with creating a socket in-
terface. Compare this with its socket-based equivalent in Example 10-24—the loop is
the same, but we don’t need to connect to sockets first (the spawning parent reads the
normal output stream), and don’t need to manually flush output as it’s produced (the
-u flag in the spawning parent prevents buffering).


Example 10-27. PP4E\Gui\Tools\pipe-nongui.py


non-GUI side: proceed normally, no need for special code


import time
while True: # non-GUI code
print(time.asctime()) # sends to GUI process
time.sleep(2.0) # no need to flush here


Start the GUI script in Example 10-26: it launches the non-GUI program automatically,
reads its output as it is created, and produces the window in Figure 10-15—it’s similar
to the socket-based example’s result in Figure 10-14, but displays the str text strings
we get from reading pipes, not the byte strings of sockets.


This works, but the GUI is odd—we never call mainloop ourselves, and we get a default
empty top-level window. In fact, it apparently works at all only because the tkinter
update call issued within the redirect function enters the Tk event loop momentarily to
process pending events. To do better, Example 10-28 creates an enclosing GUI and
kicks off an event loop manually by the time the shell command is spawned; when run,
it produces the same output window (Figure 10-15).


Example 10-28. PP4E\Gui\Tools\pipe-gui2.py


GUI reader side: like pipes-gui1, but make root window and mainloop explicit


from tkinter import *
from PP4E.Gui.Tools.guiStreams import redirectedGuiShellCmd


def launch():
redirectedGuiShellCmd('python -u pipe-nongui.py')


More Ways to Add GUIs to Non-GUI Code | 655
Free download pdf