gyn

Win32下的Perl,无用的select,停滞的Tk,结束吧....

Button命令与作用域

关于 Button 最诡异的事情大概就是与变量作用域相关的命令了。 Button 事件是作用域全局域下而非任何过程函数中。如果 Button 是在一个过程函数中创建的,那么该 Button 的命令之后将在不同的作用域中执行。即使是使用 binding 的事件处理,也将在全局域中执行。

我认为这是一个关于定义与执行的时间问题。举例来说,当定义一个 Button 时可以使用到一组变量,但在使用该 Button 的时候却用的是另一组变量。当遇到混合上下文环境的情况,这就变得很混乱了。以下例子中的 Button 命令使用到了两个变量: x val 。其中 x 是在执行中需要使用的全局变量,,本地变量 val 在定义 Button 时使用。

proc Trouble {args} {

   set b 0

   # Display the value of x, a global variable

   label .label -textvariable x

   set f [frame .buttons -borderwidth 10]

   # Create buttons that multiply x by their value

   foreach val $args {

      button $f.$b -text $val \

         -command "set x \[expr \$x * $val\]"

      pack $f.$b -side left

      incr b

   }

   pack .label $f

}

set x 1

Trouble -1 4 7 36

这个例子用了一个 label 来设置 textvariable 属性来显示 x 的当前值,该 x 总是一个全局变量。在这里,因为 x 不在 Trouble 中使用(只是被定义),所以不用使用 global 来说明 x 是全局变量(当然,用了也没关系)。 Button 命令之后则将在全局范围被使用。

但是这个 Button 命令的定义非常丑陋,在 foreach 中的定义的 Button 使用了本地的变量 val ,而其他变量的实值替换将发生在之后的全局范围内。因此需要前缀反斜杠使 $x expr 不在双引号被转义。

set x \[expr \$x * $val\]

我们举个反例来说,以下的这里例子中给 x 在定义过程中被直接赋值了一个常量,因而无法达到上面例子中的目的,显然是不正确的。

button $f.$b -text $val -command "set x [expr $x * $val]"

另外一个不正确的做法是对整个命令使用花括号(就是 “” )。这么做则是过犹不及了,所有的变量都将在全局范围内执行时被实值替换,这个时候 tcl 解析器可能发生提示发生错误,说找不到某些变量。

posted on 2009-04-24 08:58 gyn_tadao 阅读(484) 评论(0)  编辑 收藏 引用 所属分类: TclTk

只有注册用户登录后才能发表评论。
<2006年4月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

导航

统计

常用链接

留言簿(15)

随笔分类(126)

随笔档案(108)

相册

搜索

最新评论

阅读排行榜

评论排行榜