The bindtags Command

   

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

Table of Contents
Chapter 26.  Binding Commands to Events


The bindtags Command

A binding tag groups related bindings, and each widget is associated with an ordered set of binding tags. The level of indirection between widgets and bindings lets you group functionality on binding tags and compose widget behavior from different binding tags.

For example, the all binding tag has bindings on <Tab> that change focus among widgets. The Text binding tag has bindings on keystrokes that insert and edit text. Only text widgets use the Text binding tag, but all widgets share the all binding tag. You can introduce new binding tags and change the association of widgets to binding tags dynamically. The result is a powerful and flexible way to manage bindings.

The bindtags command sets or queries the binding tags for a widget. The general form of the bindtags command is:

 bindtags widget ?tagList? 

The following command returns the binding tags for text widget .t:

 bindtags .t => .t Text . all 

You can change the binding tags and their order. The tagList argument to bindtags must be a proper Tcl list. The following command reorders the binding tags for .t and eliminates the . binding tag:

 bindtags .t [list all Text .t] 

By default, all the Tk widgets, except a top-level, have four binding tags in the following order:

  • The widget's Tk pathname (e.g., .t). Use this binding tag to provide special behavior to a particular widget. There are no bindings on this bindtag by default.

  • The widget's class (e.g., Text). The class for a widget is derived from the name of the command that creates it. A button widget has the class Button, a text has the class Text, and so on. The Tk widgets define their default behavior with bindings on their class.

  • The Tk pathname of the widget's top-level window (e.g., .). This is redundant in the case of a top-level widget, so it is not used twice. There are no bindings on this bindtag by default. The bindings on a top-level window can be used in dialog boxes to handle keyboard accelerators.

  • The global binding tag all. The default bindings on all are used to change focus among widgets. They are described on page 517.

When there is more than one binding tag on a widget, then one binding from each binding tag can match an event. The bindings are processed in the order of the binding tags. By default, the most specific binding tag comes first, and the most general binding tag comes last.

Example 26-1 has two frame widgets that have the following behavior. When the mouse enters them, they turn red. They turn white when the mouse leaves. When the user types <Control-c>, the frame under the mouse is destroyed. One of the frames, .two, reports the coordinates of mouse clicks:

Example 26-1 Bindings on different binding tags.
 frame .one -width 30 -height 30 frame .two -width 30 -height 30 bind Frame <Enter> {%W config -bg red} bind Frame <Leave> {%W config -bg white} bind .two <Button> {puts "Button %b at %x %y"} pack .one .two -side left bind all <Control-c> {destroy %W} bind all <Enter> {focus %W} 

The Frame class has a binding on <Enter> and <Leave> that changes a frame's background color when the mouse moves in and out of the window. This binding is shared by all the frames. There is also a binding on all for <Enter> that sets the keyboard focus. Both bindings will trigger when the mouse enters a frame.

Focus and Key Events

The binding on <Control-c> is shared by all widgets. The binding destroys the target widget. Because this is a keystroke, it is important to get the keyboard focus directed at the proper widget. By default, focus is on the main window, and destroying it terminates the entire application. The global binding for <Enter> gives focus to a widget when you move the mouse over the widget. In this example, moving the mouse into a widget and then typing <Control-c> destroys the widget. Bind the focus command to <Button> instead of <Enter> if you prefer a click-to-type focus model. Focus is described in Chapter 36.

Using break and continue in Bindings

The break and continue commands control the progression through the set of binding tags. The break command stops the current binding and suppresses the bindings from any remaining tags in the binding set order. The continue command in a binding stops the current binding and continues with the command from the next binding tag.

For example, the Entry binding tag has bindings that insert and edit text in a one-line entry widget. You can put a binding on <Return> that executes a Tcl command using the value of the widget. The following example runs Some Command before the \r character is added to the entry widget. The binding is on the name of the widget, which is first in the set of binding tags, so the break suppresses the Entry binding that inserts the character:

 bind .entry <Return> {Some Command ; break} 

Note that you cannot use the break or continue commands inside a procedure that is called by the binding. This is because the procedure mechanism will not propagate the break or continue signal. Instead, you could use the -code option to return, which is described on page 80:

 return -code break 

Defining New Binding Tags

You introduce new binding tags just by using them in a bind or bindtags command. Binding tags are useful for grouping bindings into different sets, such as specialized bindings for different modes of an editor. One way to emulate the vi editor, for example, is to use two bind tags, one for insert mode and one for command mode. The user types i to enter insert mode, and they type <Escape> to enter command mode:

 bindtags $t [list ViInsert Text $t all] bind ViInsert <Escape> {bindtags %W {ViCmd %W all}} bind ViCmd <Key-i> {bindtags %W {ViInsert Text %W all}} 

The Text class bindings are used in insert mode. The command to put the widget into command mode is put on a new binding tag, ViInsert, instead of changing the default Text bindings. The bindtag command changes the mode by changing the set of binding tags for the widget. The %W is replaced with the name of the widget, which is the same as $t in this example. Of course, you need to define many more bindings to fully implement all the vi commands.


       
    Top
     



    Practical Programming in Tcl and Tk
    Practical Programming in Tcl and Tk (4th Edition)
    ISBN: 0130385603
    EAN: 2147483647
    Year: 1999
    Pages: 478

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net