The tklib library contains a menubar package that implements a menubar class. This class can be used to create and manage menubars in toplevel windows. The class doesn't depend on a widget framework and therefore can be used with or without a framework (e.g. Bwidget, IWidget, Snit, etc.). Some of the features of this package are:
The package is written in pure Tcl/Tk but it uses TclOO so 8.6 or greater is suggested.
-- Tom Krehbiel
The screen shots in the following examples were created using the demo code that is part of the menubar package. You can use this code as a starting point for implementing any special feature you my need for your application.
The following screen shots illustrate what is meant by scope control in the menubar class. In the screen shots below the same instance of the menubar class has been installed in each of the two toplevel windows. Below the windows are two menus that have been torn off from the same location in the menubar of each of the toplevel windows.
In this first screen shot illustrates what is meant by global scope. Each of these menus was created using the global (i.e. default) scope. As a result the value of the items are the same for both menus and changing one menu will cause the other menu to also be changed.
This second screen shot is similar to the first but the menus have been created using the local scope modifier. Notice that even though the menus have identical items the value of the items on the left are different from the items on the right. These menus have values that are scoped local to their associated toplevel window.
The following two screen shots illustrate how tab selection can be used to control the value settings of check and radio buttons. Notice that in the first screen shot tab "One" is selected in both toplevel windows and in the second screen shot tab "Two" is selected.
This screen shot illustrates dynamic menu extension. This menu has a dynamic extension that starts at the horizontal separator. All of the "Item"s and the "Mark" were added by clicking on the appropriate command buttons. The "Mark" was also moved up from its initial location at the end of the menu. This demo code is designed to test and illustrate the use of the group.xxx commands but these commands can of course also be used without any visible menu items.
Creates an instance of the menubar Class.
menubar new ?options?:
Create and return a new instance of the menubar class. The menubar class encapsulates the definition, installation and dynamic behavior of a menubar. The class doesn't depend on a widget framework and therefore can be used with or without a framework (e.g. Bwidget, IWidget, Snit, etc.). Unlike other Tk widget commands, the menubar command doesn't have a pathName argument because menubars are handled by the display manager and not the application.
The following standard options can be used when creating a menubar instance. The effect of these options is platform specific.
http://docs.activestate.com/activetcl/8.5/tcl/TkCmd/options.htm#M-activebackground%|%-activebackground%|% http://docs.activestate.com/activetcl/8.5/tcl/TkCmd/options.htm#M-activeborderwidth%|%-activeborderwidth%|% http://docs.activestate.com/activetcl/8.5/tcl/TkCmd/options.htm#M-activeforeground%|%-activeforeground%|% http://docs.activestate.com/activetcl/8.5/tcl/TkCmd/options.htm#M-background%|%-background%|% http://docs.activestate.com/activetcl/8.5/tcl/TkCmd/options.htm#M-borderwidth%|%-borderwidth%|% http://docs.activestate.com/activetcl/8.5/tcl/TkCmd/options.htm#M-cursor%|%-cursor%|% http://docs.activestate.com/activetcl/8.5/tcl/TkCmd/options.htm#M-disabledforeground%|%-disabledforeground%|% http://docs.activestate.com/activetcl/8.5/tcl/TkCmd/options.htm#M-font%|%-font%|% http://docs.activestate.com/activetcl/8.5/tcl/TkCmd/options.htm#M-foreground%|%-foreground%|% http://docs.activestate.com/activetcl/8.5/tcl/TkCmd/options.htm#M-relief%|%-relief%|%
An instance of the menubar class provides methods for compiling a description of the menubar, configuring menu items and installing the menubar in toplevel windows.
A menubar can be thought of as a tree of cascading menus. Users define a menubar using a language that results in a human readable description of a menubar. The description of the menubar is then compiled by an instance of the menubar class after which it can be installed in one or more toplevel windows.
By default a menubar instance is kept synchronized in all toplevel windows where it is installed. This means the state of radiobuttons, checkboxs, etc. are the same for all installed toplevel windows.
The menubar class provides many unique capabilities that are not found in other tcl/tk menubar implementation. Some of these are:
body == definitions definitions ::= { <ignore> | <definition> | <definition> <definitions> } ignore ::= { <nl> | <white-space> <nl> | # <comment> <nl> } definition ::= { <command> | <checkbutton> | <radiobutton> | <separator> | <group> | <menu> } command ::= <label> C <tag> <nl> checkbutton ::= <label> X { <tag> | <tag>+ } <nl> radiobutton ::= <label> R { <tag> | <tag>+ } <nl> separator ::= <dummy> S <tag> <nl> group ::= <dummy> G <tag> <nl> menu ::= <label> { M:<tag> | M:<tag>+ } <nl> <definitions> WHERE:
Type | Name | Description |
---|
C | Command | The C type entry is the most common type of entry. This entry executes a command when it is invoked. |
X | Checkbutton | A X type entry behaves much like a Tk checkbutton widget. When it is invoked it toggles back and forth between a selected and deselected states. The value of a checkbutton is a boolean (i.e. 1 or 0). By default all checkbuttons are deselected. If you want the checkbutton to be initially selected then include a trailing plus (+) with the tag name. |
R | Radiobutton | A R type menu entry behaves much like a Tk radiobutton widget. Each radiobutton entry is a member of a radiobutton group that controls the behavior of the radiobuttons in the group. All radiobuttons in a group are given the same tag name. In the example below Red, Green and Blue all have the same tag and are therefore all in the same radiobutton group. A trailing plus (+) on the tag name of a radiobotton entry will cause the entry to be the initially selected entry. |
S | Separator | A S type menu is an entry that is displayed as a horizontal dividing line. A separator may not be activated or invoked, and it has no behavior other than its display appearance. The label and tag value for a separator are ignored. |
G | Command Group | The G type menu entry marks a location in the menu tree where entries can be dynamically added and removed. Menu extension can only occur at the end of a menu so G type entries must be the last item on a menu. A G type entry is rendered as a separator line. The group.<???> sub-commands are used to manipulate command group entries. |
M | Menu | An M type entry is used to define both menubar menus and cascading menus. Menu entries are the most complicated of the 6 menu types. A menu entry is composed of three list elements. The first element of the list is its label. The second element of the list is a composite string consisting of a type identifier (M) followed by an optional tag (beginning with a ':' separator) and finally an optional plus (+) which indicates that the menu is a tear-off menu. The final element of the list is a LIST VALUE. |
Syntax for tag-settings.
tag-settings ::= { <ignore> | <value> | <value> <tag-settings> } ignore ::= { <nl> | <white-space> <nl> | # <comment> <nl> } value ::= <tag> <option-value> <nl>
These option are the same as those described for menu entries in the Tk menu documentation.
-activebackground -activeforeground -background -bitmap -columnbreak -compound -font -foreground -hidemargin -image -indicatoron -label -selectcolor -selectimage -state
-bind {<uline> <accel> <sequence>}
The value of the -bind option is a three element list where the values are as follows.
element | description |
---|---|
uline | An integer index of a character to underline in the entry. This value performs the same function as the Tk menu -underline option. If this value is an empty string then no underlining is performed. |
accel | A string to display at the right side of the menu entry. The string normally describes an accelerator keystroke sequence that may be typed to invoke the same function as the menu entry. This value performs the same function as the Tk menu -accelerator option. If this value is an empty string then no accelerator is displayed. |
sequence | A bind sequence that will cause the entries associated command to fire. |
-command <cmdprefix>
The <cmdprefix> value of the -command option is a command prefix that is evaluated when the menu entry is invoked. By default the command callback is evaluate in the namespace where the install method was executed. Additional values are appended to the cmdprefix and are thus passed to the callback command as argument. These additional arguments are defined in the table below.
entry type | arguments |
---|---|
command | 1) The pathname of the toplevel window that invoked the callback. |
checkbutton | 1) The pathname of the toplevel window that invoked the callback. 2) The checkbutton's tag name 3) The new value for the checkbutton |
radiobutton | 1) The pathname of the toplevel window that invoked the callback. 2) The radiobutton's tag name 3) The label of the button that was selected |
group | 1) The pathname of the toplevel window that invoked the callback. |
-sync {yes | no}
The -sync option can only be configured in the context of an install script and will only effects the behavior of checkbutton and radiobutton entries. When the value is 'yes' the internal value of the menu entry is the same across all installed toplevel windows. When the value is 'no' each toplevel window will have a separate internal value for the entry.
argument | type | description |
---|---|---|
tag | string | The tag name of the command group. |
label | string | The displayed label for the menu entry. |
cmd | string | A command prefix that will be used for callback command. |
accel | string | An accelerator string that will be displayed next to the entry label. |
sequence | string | A bind sequence that will be bound to the callback command. |
state | enum | Sets the active state of the command. One of: normal, disabled, active |
package require Tcl package require Tk package require menubar set tout [text .t -width 25 -height 12] pack ${tout} -expand 1 -fill both set mbar [menubar new \ -borderwidth 4 \ -relief groove \ -foreground black \ -background tan \ ] ${mbar} define { File M:file { Exit C exit } Edit M:items+ { # Label Type Tag Name(s) # ----------------- ---- --------- "Cut" C cut "Copy" C copy "Paste" C paste -- S s2 "Options" M:opts { "CheckList" M:chx+ { Coffee X coffee+ Donut X donut Eggs X eggs } "RadioButtons" M:btn+ { "Red" R color "Green" R color+ "Blue" R color } } } Help M:help { About C about } } ${mbar} install . { ${mbar} tag.add tout ${tout} ${mbar} menu.configure -command { # file menu exit {Exit} # Item menu cut {CB Edit cut} copy {CB Edit copy} paste {CB Edit paste} # boolean menu coffee {CB CheckButton} donut {CB CheckButton} eggs {CB CheckButton} # radio menu color {CB RadioButton} # Help menu about {CB About} } -bind { exit {1 Cntl+Q Control-Key-q} cut {2 Cntl+X Control-Key-x} copy {0 Cntl+C Control-Key-c} paste {0 Cntl+V Control-Key-v} coffee {0 Cntl+A Control-Key-a} donut {0 Cntl+B Control-Key-b} eggs {0 Cntl+C Control-Key-c} about 0 } -background { exit red } -foreground { exit white } } proc pout { txt } { global mbar set tout [${mbar} tag.cget . tout] ${tout} insert end "${txt}\n" } proc Exit { args } { puts "Goodbye" exit } proc CB { args } { set alist [lassign ${args} cmd] pout "${cmd}: [join ${alist} {, }]" } wm minsize . 300 300 wm geometry . +4+4 wm protocol . WM_DELETE_WINDOW exit wm title . "Example" wm focusmodel . active pout "Example started ..."
This implementation uses TclOO so it requires 8.6. The code has been tested on Windows (Vista), Linux, OSX (10.4) and Solaris however on OSX the Tk menu command doesn't behave like it does on the other platforms. I have observed the following issues on OSX (1) the -background option doesn't work for the toplevel menubar items but does work for sub-items (2) the -underline option doesn't work but the {apple} key seems to have a predefined behavior that provides some short cuts to the commands (3) Tk key bindings don't work (4) the -accelerator options sort of works but the string is truncated.
Copyright (c) 2009 Tom Krehbiel <[email protected]> All rights reserved.