8.3 Menubars

keyboard accelerators

A menubar is a frame widget containing several menubutton widgets. To each of the menubutton widgets a menu is attached. The menu contains menuitems being either radiobutton entries, checkbutton entries, command entries (similar to button widgets), separator entries or cascade entries to which sub menus are attached. The menu entries can be equipped with keyboard accelerators describing key event bindings that can be used to invoke the action of the menu entry. A keyboard accelerator must be added to the menu entry and the right event binding needs to be created.

Creating a menubar by hand has to follow this structure and is inconvenient due to the large numbers of different kinds of widgets and menu entries that are to be created. To ease the creation of a menubar, the TkTools module provides the procedure TkTools.menubar that creates to a given specification a menubar and creates keyboard accelerators with the right event bindings. The specification of a menubar consists of messages used to initialize the necessary widgets and entries, where the label determines the kind of entry to be created.

Figure 8.3 shows an example for menubar creation. The procedure TkTools.menubar takes two widgets and two menubar specifications as input and returns a frame containing the widgets for the menubar. The widget given as first argument serves as parent for the menubar's frame, whereas the widget given as second argument receives the key bindings for the accelerators. The specification given as third (fourth) argument describe the left (right) part of the menubar.


V={New Tk.variable tkInit(0)}
B={TkTools.menubar W W
   [menubutton(text:'Test' underline:0
               menu: [command(label:   'About test' 
                              action:  Browse#about
                              key:     alt(a)
                              feature: about)
                      separator
                      command(label:   'Quit' 
                              action:  W#tkClose
                              key:     ctrl(c)
                              feature: quit)]
                      feature: test)
    menubutton(text:'Options' underline:0
               menu: [checkbutton(label: 'Incremental' 
                                  var: {New Tk.variable tkInit(false)})
                      separator
                      cascade(label: 'Size' 
                              menu: [radiobutton(label:'Small' 
                                                 var:V value:0)
                                     radiobutton(label:'Middle' 
                                                 var:V value:1)
                                     radiobutton(label:'Large' 
                                                 var:V value: 2)])])]
   nil}
F={New Tk.frame tkInit(parent:W width:10#c height:5#c bg:ivory)}
{Tk.send pack(B F fill:x)}

Figure 8.3: A menubar.


A menubar specification consists of a list of menubutton messages. The valid options are those for the tkInit method of a menubutton widget object, where the parent field is not necessary, and the additional options menu and feature. The value for the menu option must be a list of specifications for the menu entries. The menu entries are specified similar to the menubuttons, the allow for the additional options feature, key, and event.

The value for the key describes the keyboard accelerator and event binding to be created. They can be used as follows:

key option value

accelerator

event binding

a

a

a

ctrl(a)

C-a

<Control-a>

alt(a)

A-a

<Alt-a>

alt(ctrl(a))

A-C-a

<Alt-Control-a>

ctrl(alt(a))

C-A-a

<Control-Alt-a>

In case one wants to use different event bindings than those generated from the key option value, one can specify the event pattern as value for the option event.

The feature options for menubuttons and menu entries attach features to the created objects such that the object get accessible by these features. For instance, to disable the ``About test'' entry is possible with

{B.test.about tk(entryconfigure state:disabled)}

The menus attached to menubuttons or to cascade entries can be accessed under the feature menu. For instance the first tear off entry from the ``Test'' menu can be removed with

{B.test.menu tk(configure tearoff:false)}

It is possible to extend a menubar created with TkTools.menubar with further entries. The following statement adds a menu entry just before the Quit entry:

A={New Tk.menuentry.command tkInit(parent:B.test.menu
                                   before:B.test.quit
                                   label: 'Exit')}

which can be deleted and removed from the menu again by:

{A tkClose}


Christian Schulte
Version 1.4.0 (20080702)