Previous section   Next section

Practical Programming in Tcl & Tk, Third Edition
By Brent B. Welch

Table of Contents
Chapter 27.  Buttons and Menus

Menus and Menubuttons

A menu presents a set of button-like menu entries to users. A menu entry is not a full fledged Tk widget. Instead, you create a menu widget and then add entries to the menu as shown in the following examples. There are several kinds of menu entries:

  • Command entries are like buttons.

  • Check entries are like checkbuttons.

  • Radio entries are like radiobuttons.

  • Separator entries are used to visually set apart entries.

  • Cascade entries are used to post submenus.

  • Tear-off entries are used to detach a menu from its menu button so that it becomes a new top-level window.

A menubutton is a special kind of button that posts (i.e., displays) a menu when you press it. If you click on a menubutton, then the menu is posted and remains posted until you click on a menu entry to select it, or click outside the menu to dismiss it. If you press and hold the menubutton, then the menu is unposted when you release the mouse. If you release the mouse over the menu, it selects the menu entry that was under the mouse.

You can have a command associated with a menubutton, too. The command is invoked before the menu is posted, which means you can compute the menu contents when the user presses the menubutton.

Our first menu example creates a sampler of the different entry types:

Example 27-6 A menu sampler.


menubutton .mb -text Sampler -menu .mb.menu
pack .mb -padx 10 -pady 10
set m [menu .mb.menu -tearoff 1]
$m add command -label Hello! -command {puts "Hello, World!"}
$m add check -label Boolean -variable foo \
   -command {puts "foo = $foo"}
$m add separator
$m add cascade -label Fruit -menu $m.sub1
set m2 [menu $m.sub1 -tearoff 0]
$m2 add radio -label apple -variable fruit -value apple
$m2 add radio -label orange -variable fruit -value orange
$m2 add radio -label kiwi -variable fruit -value kiwi

The example creates a menubutton and two menus. The main menu .mb.menu is a child of the menubutton .mb. This relationship is necessary so that the menu displays correctly when the menubutton is selected. Similarly, the cascaded submenu .mb.menu.sub1 is a child of the main menu. The first menu entry is represented by the dashed line. This is a tear-off entry that, when selected, makes a copy of the menu in a new top-level window. This is useful if the menu operations are invoked frequently. The -tearoff 0 argument is used when creating the submenu to eliminate its tear-off entry.

The command, radio, and check entries are similar to the corresponding button types. The configuration options for menu entries are similar to those for buttons. The main difference is that the text string in the menu entry is defined with the -label option, not -text. Table 27-6 gives the complete set of options for menu entries.

The cascade menu entry is associated with another menu. It is distinguished by the small right arrow in the entry. When you select the entry, the submenu is posted. It is possible to have several levels of cascaded menus. There is no limit to the number of levels, except that your users will complain if you nest too many menus.

A Menu Bar

You can create a menu bar manually by packing several menubuttons into a frame. The default bindings on menubuttons are such that you can drag your mouse over the menu bar and the different menus will display as you drag over their menubutton.

Tk 8.0 lets you create a menu bar as a horizontal menu that is associated with a top-level window. On Windows and UNIX the menu is displayed along the top of the window. On Macintosh this menu replaces the main menu along the top of the screen when the window is activated. The menu bar menu should have all cascade entries so that when you select an entry, another menu is displayed. This is illustrated in Example 27-7. It defines variables that store the names of the menu widgets:

set $m [menu .menubar.m$m]

This creates a variable named File, Edit, and Help that store the names of the menu widgets. This trick is generalized on page 400 in a package that hides the menu widget names.

Example 27-7 A menu bar in Tk 8.0.
menu .menubar
# attach it to the main window
. config -menu .menubar
# Create more cascade menus
foreach m {File Edit Help} {
   set $m [menu .menubar.m$m]
   .menubar add cascade -label $m -menu .menubar.m$m
$File add command -label Quit -command exit
# add more menu items...

System Menus

The Tk 8.0 menu bar implementation can add entries to the Windows system menu, the Macintosh Apple menu, and the Help menu on all platforms. This works by recognizing special names. For example, if the menu bar is .menubar, then the special names are .menubar.system, .menubar.apple, and .menubar.help. The Help menu is right justified on all platforms. The Apple menu is normally used by applications for their About... entry. The entries you add to the Apple menu are added to the top of the menu. The System menu appears in the Windows title bar and has entries such as Close and Minimize.

Pop-Up Menus

A pop-up menu is not associated with a menubutton. Instead, it is posted in response to a keystroke or other event in the application. The tk_popup command posts a pop-up menu:

tk_popup menu x y ?entry?

The last argument specifies the entry to activate when the menu is posted. It is an optional parameter that defaults to 1, which avoids the tear-off entry in position zero. The menu is posted at the specified X and Y coordinates in its parent widget.

Option Menus

An option menu represents a choice with a set of radio entries, and it displays the current choice in the text of the menubutton. The tk_optionMenu command creates a menubutton and a menu full of radio entries:

tk_optionMenu w varname firstValue ?value value ...?

The first argument is the pathname of the menubutton to create. The second is the variable name. The third is the initial value for the variable, and the rest are the other choices for the value. The menubutton displays the current choice and a small symbol, the indicator, to indicate it is an option menu.

Multicolumn Palette Menus

Tk 8.0 adds a -columnbreak menu entry attribute that puts the entry at the top of a new column. This is most useful when the menu consists of several images that are arranged as a palette. Set the entry's image with the -image attribute. You can create checkbutton and radiobutton entries that have images and no indicator by using the -hidemargin attribute. In this case, a selected entry is indicated by drawing a solid rectangle around it.

      Previous section   Next section