Chapter 12. The Menu System
This chapter describes the menu system: its components, how to use
them, and how they behave in a Unix and Win32 environment. Of primary
interest are menubars and conventional linear menus (pulldown,
option, and popup), although at chapter's end, we do visit a
new kind of menu, the pie menu.
Typically, a menu contains commands that aren't used
frequently, such as configuration options, File Open, File Close,
Help, and so on. Commands that are used frequently may not be
appropriate for menus and should be placed directly in the window to
provide easier access for the user. Some examples of how menus might
be used are for:
Creating a File, Edit, and Help menubar across the top of your
Displaying a list of fonts from which the user can choose, with the
selected font marked with a checkmark
Displaying a list of editing commands that become available when the
user right-clicks on another object in your window (such as a Listbox
or Entry widget)
Making a Menu pop up with a click of a button
You can build each of these different types of menus with the basic
12.1. Menu System Components
First, let's take a quick tour of the components of a menu.
12.1.1. Menus and Menu Items
foundation of the menu system is the Menu widget, a rectangular
window that, as a result of some event, appears out of the ether and
displays one or more columns of menu items. The
event that causes the menu to appear is often the press of a
Menubutton or keyboard character, but could just as well be a
mouseclick or even a callback. The action of making a menu appear is
called posting; making a menu disappear is
called unposting. There are six flavors of menu
item, shown in Figure 12-1:
separator, and tearoff.
Figure 12-1. Important components of the menu system
With the exception of a separator, clicking
a menu item initiates item-specific behavior, such as executing a
callback, posting a menu, or perhaps setting a Perl variable.
We'll examine the various menu items in detail shortly.
cascade menu item posts another menu immediately to the right of the
cascade. The new menu may have menu items of any number or type,
including another cascade. A series of cascades are posted in quick
succession from left to right, hence the menu item's name.
A checkbutton menu item works just like the Checkbutton widget
described in Chapter 4, "
Button, Checkbutton, and Radiobutton Widgets".
Clicking a command menu item invokes a
A radiobutton menu item works just like the Radiobutton widget
described in Chapter 4, "
Button, Checkbutton, and Radiobutton Widgets".
A separator menu item is a passive line used to divide a Menu into
menu item (when present) is always Menu index zero. After clicking a
tearoff, you can drag the Menu somewhere so it's always
available for fast access.
12.1.2. Menu Indexes
methods expect a menu item index that specifies
which menu item to operate upon. The following are valid menu
Every menu item is identified by an integer ordinal, starting at zero
for the topmost menu item and increasing linearly downward. By
default, each menu has a tearoff menu item that is ordinal zero
(tearoffs are the dashed lines at the tops of menus). Pressing the
tearoff reparents the menu by cloning it in a new Toplevel, so you
can move the menu about in its own window.
The keyword active,
which means the menu item that is currently selected (the mouse is
over it and it is highlighted). If there are no menu items active,
active means the same as none.
The keywords end or
last, which mean the last menu item in the Menu.
If there are no items in the Menu, end means the
same as none.
none, which means no menu item is selected.
A pixel y coordinate of the form @pixel_offset,
where pixel_offset is an integer, relative to the
Menu's top-left corner.
A regular expression matched against the
menu item's -label option. Typically,
referring to a menu item by label rather than by ordinal is
preferred, because the code should still work even if the number of
menu items changes.
12.1.3. Manipulating Menus
Configure a Menu widget using the
configure and cget methods,
just like any other widget. If you're unfamiliar with these
methods, see Chapter 13, "Miscellaneous Perl/Tk Methods".
Here are some
other Menu methods:
- $menu->clone(parent_menu, clone_type)
Clones a Menu,
but you never call it yourself. Tk makes clones of menubar and
tearoff Menus. Enter perldoc
Tk::Menu for details.
- $menu->post(x, y)
Posts a Menu at
root window coordinates
y). This method is most often superseded
by the Post or Popup methods.
Unmaps a Menu
so it's no longer displayed.
12.1.4. Manipulating Menu Items
Configuring menu items is analogous to
configuring widgets, except that we want to limit our activities to
one menu item; that's what the
entryconfigure and entrycget
methods are for. The format is:
$menu->entryconfigure(index, -option => value);
which can be in any of the previously described forms, specifies
which menu item to configure. To fetch the value of a particular menu
item option, use:
Of course, there are other things you can do with menu items:
menu item at index the sole active menu
- $menu->delete(index [, index_end])
item index or the range
integer ordinal of the menu item at index,
where index can be any of the previously
- $menu->insert(index, type [, options])
new menu item of type before
type may be cascade,
radiobutton, or separator
callback associated with menu item index
menu associated with the cascade menu item
Returns a string
indicating the type of menu item at index
y coordinate of the top-left pixel of the menu item at
Most nontrivial applications have
menubars arrayed across the tops of their
MainWindows (or any Toplevels for that matter). Arranged within a
menubar is a series of menubuttons, which, when
pressed, post menus. Unfortunately, these days the term menubutton is
somewhat of a misnomer, because in modern Tks, the menubutton is not
an actual Menubutton widget but a cascade menu item. This came about
because of menu system support for multiple operating systems.
Prior to Perl/Tk Version 8, menubars were Frames filled with
Menubutton widgets, and programmers were responsible for managing the
geometry and appearance of the entire apparatus. Perl/Tk Versions 8
and above support a native look and feel for Unix and
Win32, so to keep menubar management simple
and consistent from the user and application developer points of
view, a new menubar management scheme was devised. The basic idea is
that the menubar is just a standard Menu widget associated with a
MainWindow or Toplevel widget, and cascade menu items fill the role
of Menubuttons. In fact, these statements created the menubar portion
of Figure 12-1:
$mw->configure(-menu => my $menubar = $mw->Menu);
my $file = $menubar->cascade(-label => '~File');
my $edit = $menubar->cascade(-label => '~Edit');
my $help = $menubar->cascade(-label => '~Help');
To keep things simple, we'll call menubar buttons that post
menus "menubuttons," whether they're real
Menubuttons or just cascade menu items. Menubutton widgets are
discussed in a later section.
menu system is also aware of special operating system-dependent
menubuttons, which is why the Help menubutton in Figure 12-1 is right justified (a custom in the Unix
world). Under Mac OS, which always has a Help menubutton at the top
of the display, Help menu items are appended to
the existing Help items. Similarly, Apple menu items are
prepended to the existing Apple menu items.
Later on, we'll see how to augment the System menubutton on
In summary, Tk 8 menubars have these
benefits over the classical Frame/Menubutton approach:
Identical programming interface regardless of the underlying
Native look and feel for enhanced user experience
Automatic geometry management of the menubar and its buttons
Special processing for Apple, Help, and System menubuttons
Figure 12-2 shows how the code that produced Figure 12-1 is rendered on a Win32 machine. In particular,
note how the Help menubutton is not treated
specially and not right justified.
Figure 12-2. Compare this picture produced on Win32 with Figure 12-1, produced on Unix
12.1.6. Menu Options
any widget, there are options that affect how the Menu looks and
behaves. The following is a list of the options available for the
- -activebackground => color
Sets the background color behind
the active menu item.
- -activeborderwidth => amount
Sets the edge width of the active menu
- -activeforeground => color
Sets the text color of the active
- -background => color
Sets the background color of the
- -borderwidth => amount
Sets the width of the menu's
- -cursor => cursorname
Sets the cursor displayed when the mouse
cursor is over the menu.
- -disabledforeground => color
Sets the text color of any disabled menu
- -font => font
Sets the font of the menu text.
- -foreground => color
Sets the color of the text in the
- -menuitems => list
Defines a list of items to create
in the menu.
- -postcommand => callback
callback that is invoked before the menu is posted to the screen.
- -relief => 'flat' | 'groove' | 'raised' | 'ridge' | 'sunken'
Sets the relief of the menu's edges.
- -selectcolor => color
Sets the color of the selection
box in checkbutton or radiobutton items.
- -takefocus => 0 | 1| undef
Controls the ability to use the
keyboard to traverse the menu.
- -tearoff => 0 | 1
whether or not the menu will contain the tearoff item as the first
- -tearoffcommand => callback | 1
Invokes the callback when a Menu is torn
off. The callback is passed references to the Menu and new Toplevel
- -title => string
Title of the torn-off Toplevel.
Copyright © 2002 O'Reilly & Associates. All rights reserved.