Brandin
Brandin

Reputation: 916

Error: unknown option "-state" occurs when running a script named button.tcl

I created a simple script to try out the Tk button widget but I encountered an unexpected error.

#!/usr/bin/env tclsh
package require Tk

set w .demo
toplevel $w

ttk::button $w.ok -text OK -command {puts "OK Pressed"}
grid $w.ok

When I run this, I get two windows: one window that gets created by the package require Tk command called "button" in the title bar (because I named the script "button.tcl") and the other which is created by the toplevel $w command and is called "demo" in the title bar.

The "demo" top-level window behaves as expected. If I click the OK button it executes the script command. The problem is, if I move my mouse inside the "button" window I get the following error dialog:

Error: unknown option "-state"

Details>>

unknown option "-state"
unknown option "-state"
    while executing
"$w cget -state"
    (procedure "tk::ButtonEnter" line 3)
    invoked from within
"tk::ButtonEnter ."
    (command bound to event)

Failing button application with error message

I am using ActiveTcl 8.6.4.1 and Windows 8. I also tried variations of running this, such as using the wish interpreter instead of tclsh, leaving off package require Tk, using other widgets instead, etc.

The only thing strange thing is, if I rename the script file to something other than "button.tcl", the error does not occur, which solves the immediate problem but still leaves me with questions:

  1. Why does this error happen when the script happens to be called "button.tcl"?
  2. If there is a potential problem with the using the name "button.tcl" for a script file, are there any other such file names that I should watch out for?

Upvotes: 3

Views: 1478

Answers (1)

Peter Lewerin
Peter Lewerin

Reputation: 13252

From "Practical Programming in Tcl and Tk" by Brent B. Welch et al, page 476:

Don't use widget names for script names.
The application class name becomes the class name for the main toplevel window. For example, if you use a script name like button.tcl, the class for . becomes Button. This causes it to inherit all the standard Button bindings and attribute values, which can cause problems in your application.

Looking inside button.tcl in the tk8.6 library, the problem is apparent. This script binds the class Button and the Enter event to an invocation of tk::ButtonEnter with the window name as argument. Inside tk::ButtonEnter, the window is queried for its -state option value. Since your script is named button.tcl, this binding will be fired when the mouse enters your main window.

Upvotes: 4

Related Questions