Perl/Tk Menus: Past, Present and Future
Checkbuttons
Figure 3 shows radio-button and checkbutton menu items -- the checkbuttons are in the lower half of the menu.
Figure 3: Button Menus
Both menu items have an indicator on their left that advertises whether they are on or off. A checkbutton's state (whether it's selected or not) is stored in a Perl scalar. Here's a typical checkbutton creation command:
$menu->checkbutton(-label => 'Autosize line', -variable => \$autosize, -onvalue => 1, -offvalue => 0, -underline => 0, -command => \&line); |
So Tk sets $autosize to 1 whenever the item is selected, and 0 when it's deselected. The reverse is true as well -- changing the variable to 0 or 1 changes the indicator. Also, the character at label position zero is underlined, and the subroutine &line is called whenever there's a state change.
Radiobuttons
Radiobuttons select a single item from a list of related items. (If you have a one item list, just use a checkbutton.) Each radiobutton in a group uses the same Perl scalar to store its value, like this:
$menu->radiobutton(-label => '1 point', -variable => \$point, -value => 1, -underline => 0, -command => \&point); $menu->radiobutton(-label => '2 point', -variable => \$point, -value => 2, -underline => 0, -command => \&point); |
The scalar $point takes on one of several point sizes as the radiobutton indicators are clicked. And like checkbuttons, changing the variable's value changes the Tk indicator, and invokes a callback.
Tk 4 Menubars
Many Perl/Tk programs manually build their menubars by packing menubuttons into a frame. Some buttons are left-justified, some are right-justified. The following statements are from program menubar1, and produce a menubar identical to what you see in Figure 4.
![]() |
my $mw = MainWindow->new; $mw->geometry('300x50'); my $menubar = $mw->Frame(qw/-relief raised -borderwidth 2/); $menubar->pack(qw/-fill x/); my $file = $menubar->Menubutton(qw/-text File-underline 0/); my $cas1 = $menubar->Menubutton(qw/-text Cascades-underline 3/); my $help = $menubar->Menubutton(qw/-text Help -underline 0/); $file->pack(qw/-side left/); $cas1->pack(qw/-side left/); $help->pack(qw/-side right/); |
Thus far I've intentionally avoided cascades; it's time to remedy that situation by adding one (keep Figure 4 in mind). I've found that almost no one grasps how to make multi-level cascades, mainly because the sub-menu creation is so obscure.
my $cas2 = $cas1->cascade(-label => "Cascade Level 2"); $cas1->command(-label => 'Level 1'); |
The Cascades menu now has three menu items, a tearoff, a cascade and a command. The cascade item Cascade level 2 needs its sub-menu created, but the sub-menu must be a child of the Cascades menu. The following code fetches the menu reference for the parent menu, creates the sub-menu, and then configures the new cascade.
my $cas1_menu = $cas1->cget(-menu); my $cas2_menu = $cas1_menu->Menu; $cas1->entryconfigure('Cascade Level 2', -menu => $cas2_menu); $cas2->command(-label => 'Level 2', -command => sub {print "Level 2\n"}); |
Page 2 of 3
This article was originally published on August 19, 1999