Tcl/Tk:can';我不想逃避和返回

Tcl/Tk:can';我不想逃避和返回,tcl,bind,tk,Tcl,Bind,Tk,我不能bindTcl/Tk代码中的Escape和Return键。下面的代码复制了这个bug。当我按下Esc或Enter键时,我收到以下错误消息: 错误:无法读取“cmd”:没有此类变量 proc-OkCancel{cmd}{ 按钮。${cmd}.ok-文本“ok”-命令[列表myOk$cmd] 按钮。${cmd}.cancel-文本“cancel”-命令[列表myCancel.$cmd] 网格${cmd}.ok.${cmd}.cancel-Stickye 绑定。$cmd{myOk$cmd;bre

我不能
bind
Tcl/Tk代码中的
Escape
Return
键。下面的代码复制了这个bug。当我按下
Esc
Enter
键时,我收到以下错误消息:

错误:无法读取“cmd”:没有此类变量

proc-OkCancel{cmd}{
按钮。${cmd}.ok-文本“ok”-命令[列表myOk$cmd]
按钮。${cmd}.cancel-文本“cancel”-命令[列表myCancel.$cmd]
网格${cmd}.ok.${cmd}.cancel-Stickye
绑定。$cmd{myOk$cmd;break}
bind.$cmd{myCancel.${cmd};break}
}
proc myOk{cmd}{
放置“命令名为=$cmd”
}
proc myCancel{arg}{
销毁$arg
}
过程测试{}{
设置cmd“hello”
顶级。$cmd
OkCancel$cmd
}
测验

这是因为当一个事件触发时,绑定到它的脚本会在全局级别上得到评估(根据)。也就是说,在您的
绑定的情况下,脚本
myOk$cmd;按字面意思,将执行break
。因此,如果在脚本运行时全局命名空间中不存在名为“cmd”的变量,则会触发显示的错误

要解决此问题,有几种方法:

  • 在创建和绑定脚本时对
    $cmd
    替换进行评估。为此,只需将{}替换为“”以允许变量替换,也就是说,如果要编写
    bind.$cmd“myOk$cmd;break”
    则绑定的脚本将是
    myOk hello;中断
  • 将回调脚本转换为过程调用,并向其传递显式参数,如下所示:
    bind.$cmd[list mycallback$cmd]
    ,然后确保定义了接受一个参数的
    mycallback
    过程。通过这种方式,您可以编写通用事件处理程序,这些事件处理程序由绑定时所需的任何参数进行参数化
  • 使用
    namespace code
    或类似工具使脚本在定义了指定变量的指定命名空间中执行

在所有情况下,请注意,由于$cmd在某些情况下可能会扩展为一些奇怪的内容,因此最好保护整个脚本不受这种情况的影响—这就是第二个示例中的
[list…]
所做的(请参阅以获取更多信息)。

这是因为当事件触发时,绑定到它的脚本将在全局级别进行评估(根据)。也就是说,在您的
绑定的情况下,脚本
myOk$cmd;按字面意思,将执行break
。因此,如果在脚本运行时全局命名空间中不存在名为“cmd”的变量,则会触发显示的错误

要解决此问题,有几种方法:

  • 在创建和绑定脚本时对
    $cmd
    替换进行评估。为此,只需将{}替换为“”以允许变量替换,也就是说,如果要编写
    bind.$cmd“myOk$cmd;break”
    则绑定的脚本将是
    myOk hello;中断
  • 将回调脚本转换为过程调用,并向其传递显式参数,如下所示:
    bind.$cmd[list mycallback$cmd]
    ,然后确保定义了接受一个参数的
    mycallback
    过程。通过这种方式,您可以编写通用事件处理程序,这些事件处理程序由绑定时所需的任何参数进行参数化
  • 使用
    namespace code
    或类似工具使脚本在定义了指定变量的指定命名空间中执行

在所有情况下,请注意,由于$cmd在某些情况下可能会扩展为一些奇怪的内容,因此最好保护整个脚本不受这种情况的影响,这就是第二个示例中
[list…]
所做的(请参阅以获取更多信息)。

感谢您的详细解释和修复错误!最好使用
subst
命令,而不是
list
。因为在脚本的情况下,
list
可以进行不必要的转义。@GrAnd:通常不<在生成绑定脚本(和其他回调)方面,code>list通常优于
subst
,因为只要生成一个命令,就更容易正确使用。(这个问题有一个更棘手的例子,我会使用
[list…]\;break
甚至让回调过程以
返回-code break
结束)@GrAnd:我想你错了<如果要创建单个命令,则代码>列表始终优于
subst
。无法保证
subst
将生成有效列表,但
list
始终会生成有效列表。感谢您的详细解释和修复错误!最好使用
subst
命令,而不是
list
。因为在脚本的情况下,
list
可以进行不必要的转义。@GrAnd:通常不<在生成绑定脚本(和其他回调)方面,code>list通常优于
subst
,因为只要生成一个命令,就更容易正确使用。(这个问题有一个更棘手的例子,我会使用
[list…]\;break
甚至让回调过程以
返回-code break
结束)@GrAnd:我想你错了<如果要创建单个命令,则代码>列表始终优于
subst
。无法保证
subst
将生成有效列表,但
list
始终会生成有效列表。