Tk:如何使用 -command 传递变量值? [英] Tk : how to pass variable values with -command?

查看:21
本文介绍了Tk:如何使用 -command 传递变量值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

button .mltext.button -text "Apply" -command {set top_tlbl [update_text $top_tlbl $spc ] }

我收到一个错误:

can't read "spc": no such variable
while executing
"update_text $top_tlbl $spc "
invoked from within
".mltext.button invoke"

如何将变量的值传递给 update_text 函数?

How can I pass the values of the variables to the update_text function?

也许我可以从理解这一点开始:

Maybe I can start by understanding this :

(System32) 3 % expr 2 + 2
4
(System32) 4 % list expr 2 + 2
expr 2 + 2
(System32) 5 % [list expr 2 + 2]
invalid command name "expr 2 + 2"
(System32) 6 % 

依我看,最后一个应该生成expr 2 + 2,这和第一个命令是一样的——那么,为什么TCL有问题?

According to me, the last one should generate expr 2 + 2, which is the same as the first command - so, why does TCL have a problem?

谢谢..

推荐答案

在您使用 expr 的示例中,我们从字数开始.

In your examples with expr, we start by counting the words.

expr 2 + 2 有四个字:expr2+2.第一个是命令名,expr,其他的作为参数传递;expr 的文档说它连接它的参数并计算结果表达式.

expr 2 + 2 has four words: expr, 2, + and 2. The first one is the command name, expr, and the others are passed as arguments; the documentation for expr says that it concatenates its arguments and evaluates the resulting expression.

list expr 2 + 2 有五个字:listexpr2+2.第一个是命令名,list,其他的作为参数传递;list 的文档说它返回将其参数作为元素的列表.虽然我们在这里没有明确地看到它,但它的作用是准确地引入了创建单替换命令所需的引用.好的 Tcl 代码在生成代码时会大量使用 list.

list expr 2 + 2 has five words: list, expr, 2, + and 2. The first one is the command name, list, and the others are passed as arguments; the documentation for list say that it returns the list that has its arguments as elements. Though we don't see it here explicitly, what this does is introduce exactly the quoting needed to make a single substitution-free command. Good Tcl code uses list quite a lot when generating code.

[list expr 2 + 2]一个字,是调用list expr 2 + 2的结果.如果你直接将它输入到 Tcl 中,它有一个奇怪但合法的命令名称,而且你可能没有一个叫做它的命令.因此你会得到一个错误.

[list expr 2 + 2] has one word, which is the result of calling list expr 2 + 2. If you just feed that into Tcl directly, it has a weird but legal command name, and you probably don't have a command called that. Hence you get an error.

现在让我们考虑:

button .mltext.button -text "Apply" -command {set top_tlbl [update_text $top_tlbl $spc]}

根据您的评论,您是在一个过程中调用它.这意味着您需要在回调中绑定变量(在 uplevel #0 内计算,并且可能在当前过程返回后很久)而不立即执行回调.奇怪的是,您似乎也在运行时更改了 top_tlbl.

From your comments, you're calling this inside a procedure. This means that you need to bind the variables inside the callback (which is evaluated inside uplevel #0, and probably long after your current procedure has returned) without doing the callback immediately. Curiously, it looks like you're changing top_tlbl at runtime too.

让我们从最里面的部分开始.我们可以用 list 生成它就好了(忽略不同的生命周期绑定):

Let's start by thinking about the innermost part. We can generate it with list just fine (ignoring the different lifetime bindings):

list update_text $top_tlbl $spc

现在我们只需要让其他部分也能正常工作.这就是它变得繁琐的地方,你最终会得到这样的东西:

Now we've just got to make the other parts work as well. That's where it gets fiddly and you end up with something like this:

… -command "set top_tlbl \[[list update_text $top_tlbl $spc]\]"

现在让我们修复生命周期的问题:

Now let's fix the lifetime stuff:

… -command "set top_tlbl \[update_text \$top_tlbl [list $spc]\]"

这种事情在复杂的回调中非常容易出错!在这一点上,有一个小帮助程序会更容易(并且良好实践):

This sort of thing is more than a bit error-prone in complicated callbacks! At that point, it's much easier (and good practice) to have a little helper procedure:

proc do_update_text {varname value} {
    upvar #0 $varname var
    set var [update_text $var $value]
}

然后你可以做(​​注意:传递top_tlblname,而不是值):

Then you can do (note: passing the name of top_tlbl, not the value):

… -command [list do_update_text top_tlbl $spc]

全局变量名的使用可能被认为是有问题的,除非您必须记住全局命名空间主要由您的应用程序拥有.如果你想在你的应用程序的全局变量中存储变量,那就去做吧!您拥有完全的权利.

The use of global variable names might be considered to be problematic, except you've got to remember that the global namespace is mainly owned by your application. If you want to store variables in globals for your app, do it! You have the complete right.

库代码当然需要多加小心.那里的常用技术包括在其他名称空间(Tk 在内部执行此操作)或在对象中使用变量.代码并没有真正变得更复杂;它仍然建立在使用上面列出的帮助程序的实践之上.不过,传递命名空间变量名称非常简单:

Library code needs to be a bit more careful of course. The usual techniques there include using variables in other namespaces (Tk does this internally) or in objects. The code doesn't really get that much more complicated; it's still building on the practice of using helper procedures listed above. Passing a namespaced variable name is pretty easy though:

… -command [list do_update_text ::mynamespace::top_tlbl $spc]

这篇关于Tk:如何使用 -command 传递变量值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆