2016-05-07 7 views
3

Ich habe ein einfaches Skript erstellt, um das Tk-Button-Widget auszuprobieren, aber ich habe einen unerwarteten Fehler festgestellt.Fehler: unbekannte Option "-State" tritt auf, wenn ein Skript mit dem Namen button.tcl ausgeführt wird

#!/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 

Als ich das laufen ließe, erhalte ich zwei Fenster: ein Fenster, das von dem package require Tk Befehl „Knopf“ in der Titelleiste aufgerufen erstellt wird, und die andere (weil ich das Drehbuch „button.tcl“ genannt), das wird mit dem Befehl toplevel $w erstellt und heißt in der Titelleiste "demo".

Das "Demo" Top-Level-Fenster verhält sich wie erwartet. Wenn ich auf OK klicke, wird der Skriptbefehl ausgeführt. Das Problem ist, wenn ich meine Maus in dem "Knopf" Fenster verschieben ich folgenden Fehlerdialog erhalten:

Fehler: unbekanntes Option "-Zustand"

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

ich verwende ActiveTcl 8.6.4.1 und Windows 8. ich habe auch versucht, Variationen dies ausgeführt wird, wie mit dem wish Dolmetscher statt tclsh, so dass aus package require Tk, mit anderen Widgets statt, etc.

Das einzige, was seltsame Sache ist, wenn ich die Skriptdatei auf etwas anderes als "button.tcl" umbenennen, tritt der Fehler nicht auf, der das unmittelbare Problem aber noch löst lässt mich mit Fragen:

  1. Warum passiert dieser Fehler, wenn das Skript zufällig "button.tcl" genannt wird?
  2. Wenn es ein potentielles Problem mit der Verwendung des Namens "button.tcl" für eine Skriptdatei gibt, gibt es irgendwelche andere solche Dateinamen, auf die ich achten sollte?

Antwort

4

Von "Practical Programming in Tcl und Tk" von Brent B. Welch et al, Seite 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.

Blick ins Innere button.tcl in der tk8.6 Bibliothek ist das Problem offensichtlich. Dieses Skript bindet die Klassen Button und Enter an einen Aufruf von tk::ButtonEnter mit dem Fensternamen als Argument. Innerhalb tk::ButtonEnter wird das Fenster für seinen Optionswert -state abgefragt. Da Ihr Skript den Namen button.tcl hat, wird diese Bindung ausgelöst, wenn die Maus Ihr Hauptfenster betritt.

+1

Vermeiden Sie auch die Benennung von Bildern nach den Operationen, die sie ausführen. Warum? Weil das Erstellen eines Bildes mit dem Namen 'open' Ihr Programm auf mysteriöse Weise zum Scheitern bringt, da Sie einen Standard-Tcl-Befehl ersetzt haben. (Dort gewesen, das getan ...) –

+0

Anscheinend muss ich dieses Buch lesen. – Brandin