Occasionally, you may need to create multiple MainWindows in the same application. Typically, having two MainWindows in one application isn't always a wise idea, since bitmaps and images aren't shared between MainWindows, and some Tk modules are unreliable when shared. But we're going to explore it anyway, because it's an interesting exercise. To show how it's done, we'll start with an advanced "Hello Worlds" program, so named because it uses two MainWindows.
You might be wondering what useful programs might exist that take advantage of more than one screen. Nonlinear digital video editing software is a great example. A fancy high-resolution screen displays the movie in progress, and secondary screens contain editing controls. Or, any application that requires lots of screen real estate can spread its windows across multiple screens. We won't be doing any of that fancy stuff, as you'll see.
Our little program begins typically enough, importing all the required Tk symbols, subroutines, variables, classes, widgets, and methods, then opening the first MainWindow, $mw1, in the normal fashion.[22]
[22] It runs strict and with warnings enabled, as do most of the programs in this book; all yours should too, at least during development. If you fail to heed this warning, subtle (and sometimes overt) bugs will bite you, sooner rather than later.
#!/usr/local/bin/perl -w # # Advanced Hello World program using two MainWindows. use Tk; use subs qw/beep/; use strict; my $mw1 = MainWindow->new;
By default, MainWindow opens its window on the display pointed to by $ENV{DISPLAY}, which in Unix is normally :0 (assuming you haven't pointed it elsewhere). Technically, a display specification consists of three fields: [host]:server[.screen], where host is the machine name and server and screen are usually zero.
The screen number is interpreted in at least two different ways. If there are multiple physical monitors that logically act as one, they are addressed via screen number. The screens are treated as a contiguous area, so if you want to move a window from one monitor to another, just grab it and drag. Alternatively, the screen number may specify special attributes of a single monitor. For instance, the MacX server treats screen zero as a monochrome monitor and screen one as color.
We open the second MainWindow just like the first but provide a command-line hook to send it elsewhere. (See Chapter 16, "User Customization" for details on command-line processing.)
my $mw2 = MainWindow->new(-screen => $ARGV[0] ||= $ENV{DISPLAY}); $mw1->Button(-text => 'MainWindow 1 Bell', -command => [\&beep, $mw1])->pack; $mw1->Button(-text => 'MainWindow 2 Bell', -command => [\&beep, $mw2])->pack; $mw1->Button(qw/-text Quit -command/ => \&exit)->pack; MainLoop; sub beep {shift->bell}
Note that the parameter for MainWindow's constructor is -screen, not -display as you might imagine. If nothing is supplied on the command line, then both MainWindows appear on the same display, as shown in Figure 11-3.
Now pack three Buttons in the first MainWindow and set up simple callbacks to ring the bell on either of the MainWindows. Notice that each callback passes its MainWindow reference to the beep subroutine, which shift grabs from @_. (See Chapter 15, "Anatomy of the MainLoop" for more about callbacks.) As you'd expect, pressing either of the Bell Buttons sounds the display's audible alert.
This program is more interesting when $mw2 is redirected to another display,[23] where pressing its Bell Button causes the remote machine to beep.
[23] Before you can use another display, its owner must give you permission. See the section on xauth authentication in Chapter 20, "IPC with send" for details.
Copyright © 2002 O'Reilly & Associates. All rights reserved.