Tcl/Tk 绑定需要全局变量吗?

发布于 2024-11-27 07:47:51 字数 802 浏览 0 评论 0原文

我有一个控制自动测试器的 Tcl 脚本。到目前为止,它是一个控制台程序,在命令提示符处接受用户输入。一位同事编写了一个可以通过脚本启动的 Tk GUI。我自己从来没有使用过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 是一个简单更新 GUI 上文本标签的过程。

我不喜欢有一个全局变量 gUserInterfaceBarCode 用来保存序列号。有什么方法可以使用局部变量并让过程返回该值吗?

如果我理解正确的话,如果取出 tkwait 变量 gUserInterfaceBarCode 行,则该函数将不会阻塞,直到该变量发生变化。这是从 GUI 元素捕获用户输入的最佳方法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

神爱温柔 2024-12-04 07:47:51

从根本上讲,您需要有一个变量来等待。不幸的是, 的代码是在与 proc 内的代码不同的上下文(全局上下文)中执行的,并且该代码无法寻址 proc 中的局部变量。

然而,它本身并不需要一个全局变量——它只需要是全局可寻址的,我的意思是你可以使用命名空间变量,如果这让你感觉更好的话:

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 核心实现使用命名空间方法来实现其自己的内置对话框,例如“打开文件”对话框。

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:

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]

Another alternative would be to explicitly delete gUserInterfaceBarCode before returning:

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文