Для связывания Tcl / Tk требуется глобальная переменная? - PullRequest
3 голосов
/ 30 июля 2011

У меня есть скрипт Tcl, управляющий автоматическим тестером. До сих пор это была консольная программа, которая принимала пользовательский ввод из командной строки. Коллега написал графический интерфейс Tk, который можно запустить с помощью сценария. Я сам никогда не использовал Tk, поэтому не очень разбираюсь в синтаксисе.

В начале теста скрипт должен получить серийный номер устройства у оператора. Это функция, которую мой коллега написал для этого:

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 - это процедура, которая просто обновляет текстовую метку в графическом интерфейсе.

Мне не нравится тот факт, что существует глобальная переменная gUserInterfaceBarCode, которая используется для хранения серийного номера. Есть ли способ использовать вместо нее локальную переменную и вернуть процедуре это значение?

Если я правильно понимаю, если строка tkwait variable gUserInterfaceBarCode вынута, эта функция не будет блокироваться, пока эта переменная не изменится. Это лучший способ для захвата пользовательского ввода из элемента GUI?

1 Ответ

6 голосов
/ 30 июля 2011

По сути, вам нужна переменная для ожидания. К сожалению, код для <Return> выполняется в ином контексте (глобальном контексте), чем код внутри вашего процесса, и у этого кода нет способа обратиться к локальным переменным в вашем процессе.

Однако это не относится к глобальной переменной как таковой - она ​​просто должна быть глобально адресуемой, и я имею в виду, что вместо этого вы можете использовать переменную пространства имен, если это заставляет вас чувствовать себя лучше:

namespace eval GetSerialNumber {
    proc GetSerialNumber {} {

        DisplayMessage "Enter serial number:"
        .c.serialnumberbox configure -state normal
        focus .c.serialnumberbox
        bind .c.serialnumberbox <Return> { set ::GetSerialNumber::result [.c.serialnumberbox get] }
        tkwait variable ::GetSerialNumber::result
        .c.serialnumberbox configure -state disabled
        return $::GetSerialNumber::result
    }
}

set serialNum [GetSerialNumber::GetSerialNumber]

Другой альтернативой может быть явное удаление gUserInterfaceBarCode перед возвратом:

tkwait variable ::gUserInterfaceBarCode
set result $::gUserInterfaceBarCode
unset ::gUserInterfaceBarCode
return $result

Для чего бы то ни было, реализация ядра Tk использует подход к пространству имен для своих собственных встроенных диалоговых реализаций, таких как диалоговое окно «Открыть файл».

...