I have a Tcl script controlling an automated tester. So far it was a console program that took user input at the command prompt. A colleague wrote a Tk GUI that can be launched by the script. I have never used Tk myself, so I don’t understand a lot of the syntax.
At the beginning of the test the script must get a unit serial number from the operator. This is the function that my colleague wrote to do that:
proc GetSerialNumber {} {
global gUserInterfaceBarCode
DisplayMessage "Enter serial number:"
.c.serialnumberbox configure -state normal
focus .c.serialnumberbox
bind .c.serialnumberbox <Return> { set gUserInterfaceBarCode [.c.serialnumberbox get] }
tkwait variable gUserInterfaceBarCode
#grid forget .c.serialnumberbox
.c.serialnumberbox configure -state disabled
}
DisplayMessage is a procedure that simply updates a text label on the GUI.
I don’t like the fact that there is a global variable gUserInterfaceBarCode that is used to hold the serial number. Is there any way to use a local variable instead and have the procedure return that value?
If I understand correctly, if the line tkwait variable gUserInterfaceBarCode is taken out this function will not block until that variable changes. Is this the best way to capture user input from a GUI element?
Fundamentally you need to have a variable to wait on. Unfortunately, the code for the
<Return>is executed in a different context (the global context) than the code inside your proc, and there’s no way for that code to address the local variables in your proc.However, it doesn’t have to a global variable, per se — it just needs to be globally addressable, by which I mean you could use a namespace variable instead, if that makes you feel better about it:
Another alternative would be to explicitly delete
gUserInterfaceBarCodebefore returning:For what it’s worth, the Tk core implementation uses the namespace approach for its own built-in dialog implementations, like the “Open File” dialog box.