Common Tk Errors

The following problems are frequently reported by users writing Tcl/Tk programs and are easy to correct with a little guidance. This section is not meant to be a complete guide to writing Tcl/Tk, but serves to address a few common situations.

Global Scope for -variable and -textvariable

Many Tk widgets allow you to tie a widget to a Tcl variable so that changes to either the widget or variable are mirrored in the other. This handy feature makes widget data instantly available in Tcl code, without the need to access the widget command:

label .tot_rev-text 0-textvariable totalRevenue
set totalRevenue 263124 ;# updates widget also

The most common problem when using -variable and -textvariable options is forgetting that the variables the options name are referenced as global variables. If you create widgets inside of a procedure and then access the widget’s variable, be sure to define the variable as global.

proc mk_totRev {} {
    label .tot_rev -text 0 -textvariable totalRevenue
    pack .tot_rev
    global totalRevenue
    set totalRevenue 23128
}

The -command String Must Be a Tcl List

Tk widgets (particularly buttons) often let you specify code to be run when the widget is selected. This code is known as a callback. You should put the code in braces, not quotes, to prevent variables from being interpreted until the user selects the widget. This is illustrated in the following example:

set count 0
button .b -text "Increment" -command {puts $count; incr count}
pack .b

Callback scripts can be of any length, but long scripts tend to get unwieldy when included in the -command argument. It is often easier to define your callback script as a procedure and call that procedure in the callback:

proc CallBack {} {
  global count
  puts "Current value is: $count"
  incr count
}

set count 0
button .b -text "Increment" -command CallBack
pack .b

Use update to Refresh Widgets and for Event Processing

A Tk application runs as an event-driven program. When your program starts, your code builds widgets and defines callbacks until Tcl reaches the “end” of your code. At this point, Tcl has entered an event loop in which user events are processed, calling the callback scripts that you defined as -command options for widgets and bind commands. The interface is active during event processing, and updates screen widgets accordingly.

If any of your callback scripts perform a significant amount of processing, the inter face will appear to be frozen while scripts are executing. One way to prevent a frozen interface is to periodically execute the update command, which allows events to be processed. If your intent is to allow widgets to be updated without accepting new user events, use the idletasks option. In the following example, the update command allows the label widget to update the screen. Without update, the program will appear frozen.

label .l -text ""
proc count {} {
    for {set c 1;  .l configure -text 0} {$c <= 5} {incr c} {
        update
        after 1000
        .l configure -text $c
  }
}
button .b -text "count to five" -command count
pack .l .b

If your program reads and writes to sockets, or via pipes to another program, consider using file events to keep your interface active. Reading from any channel will cause the Tcl interpreter to wait until data is ready before returning. Tcl’s fileevent command provides callback processing for files and sockets.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset