February 18, 2019
Hot Topics:

Perl/Tk Menus: Past, Present and Future

  • August 19, 1999
  • By Steve Lidie
  • Send Email »
  • More Articles »


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 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.

Figure 4
Figure 4

my $mw = MainWindow->new;
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"});

That's a lot of work, and we won't go any further with this Tk 4 idiom. Much has changed, as we'll see.

Page 2 of 3

Comment and Contribute


(Maximum characters: 1200). You have characters left.



Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date