📄 ch17.htm
字号:
17.5, this was done with lines 15, 19, and 23):
<BLOCKQUOTE>
<TT><FONT FACE="Courier">-command => sub {print "$animal
\n"; } ,</FONT></TT>
</BLOCKQUOTE>
<P>
You can refer to a subroutine by using the escaped ampersand with
the name of the subroutine. Any parameters that have to be passed
to the subroutine have to be specified with the <TT><FONT FACE="Courier">-command</FONT></TT>
parameters as one list. For example, consider the following function
which creates a button with a caption of <TT><FONT FACE="Courier">Stats</FONT></TT>,
and calls the subroutine <TT><FONT FACE="Courier">do_print when
the button is pressed</FONT></TT>:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">$main->Button(-text => 'Stats',
<BR>
-command
=> [ \&do_print , $inputfile, $outputfile ]<BR>
)->pack;</FONT></TT>
</BLOCKQUOTE>
<P>
Note the backslash in front of <TT><FONT FACE="Courier">\&do_print</FONT></TT>.
This causes Perl to generate a reference to <TT><FONT FACE="Courier">sub
do_print</FONT></TT> rather than call it. The input variables,
<TT><FONT FACE="Courier">$inputfile</FONT></TT> and <TT><FONT FACE="Courier">$outputfile</FONT></TT>,
are passed by reference not by value, into <TT><FONT FACE="Courier">the
do_print</FONT></TT> subroutine.
<H3><A NAME="ArrangingtheLayoutofWidgets">Arranging the Layout
of Widgets</A></H3>
<P>
Widgets are laid out on a window using the <TT><FONT FACE="Courier">-pack</FONT></TT>,
<TT><FONT FACE="Courier">-padding</FONT></TT>, <TT><FONT FACE="Courier">-fill</FONT></TT>,
<TT><FONT FACE="Courier">-expand</FONT></TT>, and <TT><FONT FACE="Courier">-anchor</FONT></TT>
options of a widget. Windows also use a program called a geometry
manager in <TT><FONT FACE="Courier">Tk</FONT></TT>.
<P>
A geometry manager controls the arrangement of widgets in a window.
The most common geometry manager used in <TT><FONT FACE="Courier">pTk</FONT></TT>
is <TT><FONT FACE="Courier">pack</FONT></TT>. You have seen the
use of the <TT><FONT FACE="Courier">-pack</FONT></TT> function
to place buttons on a window in earlier sections of this chapter.
The <TT><FONT FACE="Courier">pack</FONT></TT> function is also
known informally as the "packer." You can invoke <TT><FONT FACE="Courier">pack</FONT></TT>
at the time of widget creation via calls like
<BLOCKQUOTE>
<TT><FONT FACE="Courier">$widget->pack;</FONT></TT>
</BLOCKQUOTE>
<P>
where <TT><FONT FACE="Courier">widget</FONT></TT> can be any of
the <TT><FONT FACE="Courier">Perl/Tk</FONT></TT> widget primitives.
The <TT><FONT FACE="Courier">pack</FONT></TT> function is often
used in conjunction with the <TT><FONT FACE="Courier">Frame</FONT></TT>
container widget to arrange your widgets much like a hierarchically
arranged set of window panes. See Listing 17.6 and Figure 17.5.<P>
<A HREF="f17-5.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f17-5.gif"><B>Figure 17.5 :</B><I>The output from Listing 17.6.</I></A>
<HR>
<BLOCKQUOTE>
<B>Listing 17.6. Packing using frames.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #!/usr/bin/perl<BR>
2 use Tk;<BR>
3<BR>
4 $main = MainWindow->new;<BR>
5<BR>
6 my $row1 = $main->Frame;<BR>
7 $row1->pack(-side => 'top');
<BR>
8 my $row2 = $main->Frame;<BR>
9 $row2->pack(-side => 'bottom');
<BR>
10 $row1->Label(-text => 'Left',
<BR>
<FONT FACE="ZAPFDINGBATS">Â</FONT>-relief
=> 'sunken' )->pack(-side => 'left');<BR>
11 $row1->Label(-text => 'Right',
<BR>
<FONT FACE="ZAPFDINGBATS">Â</FONT>-relief
=> 'sunken' )->pack(-side => 'right');<BR>
12 $row2->Label(-text => 'Left 2',
<BR>
<FONT FACE="ZAPFDINGBATS">Â</FONT>-relief
=> 'ridge' )->pack(-side => 'left');<BR>
13 $row2->Label(-text => 'Right
2', <BR>
<FONT FACE="ZAPFDINGBATS">Â</FONT>-relief
=> 'ridge' )->pack(-side => 'right');<BR>
14 MainLoop;</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
In Listing 17.6, we used two frames: one on the top and the other
on the bottom. These frames are called <TT><FONT FACE="Courier">$row1</FONT></TT>
and <TT><FONT FACE="Courier">$row2</FONT></TT> and are created
in lines 6 through 9. Then lines 10 and 11 create the two labels
in <TT><FONT FACE="Courier">$row1</FONT></TT>, and in lines 12
and 13, two more labels are created on the second frame. In this
fashion we have packed labels on frames, and the frames are then
packed onto the main window. You can think of this as building
a Mayan temple of sorts with widgets being placed one on top of
the other.
<P>
Note that <TT><FONT FACE="Courier">pack</FONT></TT> itself is
given parameters in this example. The default behavior of pack
is to have <TT><FONT FACE="Courier">-side => 'top'</FONT></TT>,
that is, align everything using the top edge. You can override
this behavior by specifying a different packing style such as
"left", "right", or "bottom".
<P>
The <TT><FONT FACE="Courier">Tk*</FONT></TT> distribution has
a file called <TT><FONT FACE="Courier">popup</FONT></TT> that
uses the <TT><FONT FACE="Courier">-anchor</FONT></TT> option to
configure the layout of the <TT><FONT FACE="Courier">Radiobutton</FONT></TT>
widgets. The output of this demo is shown in Figure 17.6. Run
the following program to get the listing with line numbers for
reference.
<P>
<A HREF="f17-6.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f17-6.gif"><B>Figure 17.6 :</B><I>Using the -anchor widget option.</I></A>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">$ nl popup | more</FONT></TT>
</BLOCKQUOTE>
<P>
There is also the <TT><FONT FACE="Courier">-anchor</FONT></TT>
configuration option for widgets. There are introductions to the
nine possible <TT><FONT FACE="Courier">-anchor</FONT></TT> values,
eight corresponding to the points on a compass and the ninth as
the center position. The nine possible values are set around
line 22 with <TT><FONT FACE="Courier">list</FONT></TT>:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">foreach $r ([qw(nw n ne)],[qw(w c e)],[qw(sw
s se)])</FONT></TT>
</BLOCKQUOTE>
<P>
In the beginning of the file, we create a small popup window
to show when a button is clicked. Rather than create this window
every time, a button is created but is not shown immediately.
Around lines 13 through 17, the subroutine <TT><FONT FACE="Courier">Show</FONT></TT>
shows this window and requests it to be invisible after one second.
<P>
In the subroutine <TT><FONT FACE="Courier">Anchor</FONT></TT>,
a master frame is created (see line 21) with a ridge around it.
Then three frames are placed on it, each with three buttons showing
the anchor positions (see lines 25 through 29). The positions
and the labels for the buttons are shown in line 22.
<P>
When setting lots of uneven widgets on the same frame, you can
make their borders the same size by using <TT><FONT FACE="Courier">-fill
=> 'style'</FONT></TT>. The style can be <TT><FONT FACE="Courier">none
| x | y | both</FONT></TT>. See the modified version of the radio
button application and contrast the code in Listing 17.7 with
the code in Listing 17.4. The output is shown in Figure 17.7,
which you can compare with Figure 17.3 to see how the buttons
with their borders are now shown and resized.<P>
<A HREF="f17-7.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f17-7.gif"><B>Figure 17.7 :</B><I>Using the <FONT FACE="Couier">-fill</FONT> option.</I></A>
<HR>
<BLOCKQUOTE>
<B>Listing 17.7. Using the </B><TT><B><FONT FACE="Courier">-fill</FONT></B></TT><B>
option.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #!/usr/bin/perl<BR>
2 <BR>
3 use Tk;<BR>
4 <BR>
5 #<BR>
6 # Using Checkbuttons and the -fill option.<BR>
7 #<BR>
8 <BR>
9 my $main = new MainWindow;<BR>
10 $main->title("fill");<BR>
11 <BR>
12 $main->Checkbutton(-text => 'One',<BR>
13 -relief => 'ridge',
<BR>
14 -command => sub {print
"One \n"; } )->pack(-fill => 'x');<BR>
15 $main->Checkbutton(-text => 'Two',<BR>
16 -relief => 'sunken',
<BR>
17 -command => sub {print
"Two \n"; } )->pack(-fill => 'x');<BR>
18 $main->Checkbutton(-text => 'Three',<BR>
19 -relief => 'groove',
<BR>
20 -command => sub {print
"Three \n"; } )->pack(-fill => 'x');<BR>
20<BR>
21 MainLoop;</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
When laying out your widgets, look at their behavior with multiple
<TT><FONT FACE="Courier">resize</FONT></TT> operations. The <TT><FONT FACE="Courier">-expand</FONT></TT>
option of either <TT><FONT FACE="Courier">pack</FONT></TT> or
the widget itself can be used to set whether the widget expands
or shrinks with its parent. Add the statement for packing the
buttons in Listing 17.8; the buttons will shrink or expand as
the main window is resized.
<HR>
<BLOCKQUOTE>
<B>Listing 17.8. Using the Expand button.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">1 $main->Checkbutton(-text => 'One',
<BR>
2 -relief =>
'ridge',<BR>
3 -command =>
sub {print "One \n"; } )->pack(-fill => 'x', -expand
=> '1');<BR>
4 $main->Checkbutton(-text => 'Two',<BR>
5 -relief =>
'sunken',<BR>
6 -command =>
sub {print "Two \n"; } )->pack(-fill => 'x', -expand
=> '1');<BR>
7 $main->Checkbutton(-text => 'Three',<BR>
8 -relief =>
'groove',<BR>
9 -command =>
sub {print "Three \n"; } )->pack(-fill => 'x',
-expand => '1');</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The output of this change to Listing 17.7 is shown in Figure 17.8. Remember to make this change to all the <TT><FONT FACE="Courier">pack</FONT></TT>
calls for the buttons.<P>
<A HREF="f17-8.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f17-8.gif"><B>Figure 17.8 :</B><I>Using the <FONT FACE="Courier"-expend</FONT> option.</I></A><P>
<H3><A NAME="UsingtheListboxandScrollbarWidgets">Using the <TT><FONT SIZE=4 FACE="Courier">Listbox</FONT></TT><FONT SIZE=4>
and </FONT><TT><FONT SIZE=4 FACE="Courier">Scrollbar</FONT></TT><FONT SIZE=4>
Widgets</FONT></A></I></H3>
<P>
Now that you know how to place items on a frame widget, let's
see how you create a list of scrollable items. For this exercise,
you'll use the <TT><FONT FACE="Courier">Listbox</FONT></TT> and
<TT><FONT FACE="Courier">Scrollbar</FONT></TT> widgets. The output
we are trying to get is shown in Figure 17.9. The code to get
this output is shown in Listing 17.9.<P>
<A HREF="f17-9.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f17-9.gif"><B>Figure 17.9 :</B><I>Using the <FONT FACE="Courier">Listbox </FONT>and <FONT FACE="Courier"> Scrollbar</FONT> widgers.</I></A><P>
<HR>
<BLOCKQUOTE>
<B>Listing 17.9. Using the </B><TT><B><FONT FACE="Courier">Listbox</FONT></B></TT><B>
and </B><TT><B><FONT FACE="Courier">Scrollbar</FONT></B></TT><B>
widgets.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #!/usr/bin/perl<BR>
2 use Tk;<BR>
3<BR>
4 my $main = new MainWindow;<BR>
5 #<BR>
6 # Provide another title ...<BR>
7 #<BR>
8 $main->Label(-relief => raised,<BR>
9 -text
=> "Tax Confusion" )->pack(-side => 'top',
-fill => 'x');<BR>
10 $main->title("Test Listbox");<BR>
11 $w_list = $main->Listbox(-relief => 'raised',<BR>
12 -setgrid
=> 'yes');<BR>
13 #<BR>
14 # Create a list of words of wisdom<BR>
15 #<BR>
16 my @items = qw( Passive activity income <BR>
does
not include the following:<BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -