output.write(line.lower())
print('end of file')
root = Tk()
Button(root, text='test streams',
command=lambda: redirectedGuiFunc(makeUpper)).pack(fill=X)
Button(root, text='test files ',
command=lambda: makeLower(GuiInput(), GuiOutput()) ).pack(fill=X)
Button(root, text='test popen ',
command=lambda: redirectedGuiShellCmd('dir *')).pack(fill=X)
root.mainloop()
As coded here, GuiOutput attaches a ScrolledText (Python’s standard library flavor) to
either a passed-in parent container or a new top-level window popped up to serve as
the container on the first write call. GuiInput pops up a new standard input dialog every
time a read request requires a new line of input. Neither one of these policies is ideal
for all scenarios (input would be better mapped to a more long-lived widget), but they
prove the general point intended.
Figure 10-8 shows the scene generated by this script’s self-test code, after capturing the
output of a Windows shell dir listing command (on the left) and two interactive loop
tests (the one with “Line?” prompts and uppercase letters represents the makeUpper
streams redirection test). An input dialog has just popped up for a new makeLower files
interface test.
Figure 10-8. guiStreams routing streams to pop-up windows
This scene may not be spectacular to look at, but it reflects file and stream input and
output operations being automatically mapped to GUI devices—as we’ll see in a mo-
ment, this accomplishes most of the solution to the prior section’s closing challenge.
Before we move on, we should note that this module’s calls to a redirected function as
well as its loop that reads from a spawned shell command are potentially blocking—
626 | Chapter 10: GUI Coding Techniques