Reputation: 916
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)
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:
Upvotes: 3
Views: 1478
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