Previous section   Next section

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

Table of Contents
Chapter 33.  The Text Widget

Tag Bindings

You can associate a tag with bindings so that when the user clicks on different areas of the text display, different things happen. The syntax for the tag bind command is similar to that of the main Tk bind command. You can both query and set the bindings for a tag. Chapter 26 describes the bind command and the syntax for events in detail.

The only events supported by the tag bind command are Enter, Leave, ButtonPress, ButtonRelease, Motion, KeyPress, and KeyRelease. ButtonPress and KeyPress can be shorted to Button and Key as in the regular bind command. The Enter and Leave events are triggered when the mouse moves in and out of characters with a tag, which is different from when the mouse moves in and out of the window.

If a character has multiple tags, then the bindings associated with all the tags will be invoked, in the order from lowest priority tag to highest priority tag. After all the tag bindings have run, the binding associated with the main widget is run, if any. The continue and break commands work inside tag bindings in a similar fashion as they work with regular command bindings. See Chapter 26 for the details.

Example 33-3 defines a text button that has a highlighted relief and an action associated with it. The example generates a new tag name so that each text button is unique. The relief and background are set for the tag to set it apart visually. The winfo visual command is used to find out if the display supports color before adding a colored background to the tag. On a black and white display, the button is displayed in reverse video (i.e., white on black.) The command is bound to <Button-1>, which is the same as <ButtonPress-1>.

The cursor is changed when the mouse is over the tagged area by binding to the <Enter> and <Leave> events. Upon leaving the tagged area, the cursor is restored. Another tag is used to remember the previous setting for the cursor. You could also use a global variable, but it is often useful to decorate the text with tags for your own purposes.

Example 33-3 An active text button.
proc TextButton { t start end command } {
   global textbutton
   if ![info exists textbutton(uid)] {
      set textbutton(uid) 0
   } else {
      incr textbutton(uid)
   set tag button$textbutton(uid)
   $t tag configure $tag -relief raised -borderwidth 2
   if {[regexp color [winfo visual $t]]} {
      $t tag configure $tag -background thistle
   } else {
      $t tag configure $tag -background [$t cget -fg]
      $t tag configure $tag -foreground [$t cget -bg]
   # Bind the command to the tag
   $t tag bind $tag <Button-1> $command
   $t tag add $tag $start $end
   # use another tag to remember the cursor
   $t tag bind $tag <Enter> \
      [list TextButtonChangeCursor %W $start $end tcross]
   $t tag bind $tag <Leave> {TextButtonRestoreCursor %W}
proc TextButtonChangeCursor {t start end cursor} {
   $t tag add cursor=[$t cget -cursor] $start $end
   $t config -cursor $cursor
proc TextButtonRestoreCursor {t} {
   regexp {cursor=([^ ]*)}[$t tag names] x cursor
   $t config -cursor $cursor

To behave even more like a button, the action should trigger upon <ButtonRelease-1>, and the appearance should change upon <ButtonPress-1>. If this is important to you, you can always embed a real Tk button. Embedding widgets is described later.

      Previous section   Next section