Tcl 在命名空间过程中未看到数组,但在过程中未看到命名空间
早上好 下面的代码显示了一个带有过程的名称空间,还有一个名为ds_out的数组 如果运行此代码并按enter按钮,则会出现错误: 错误:无法读取“ds_out(0)!:没有这样的变量 如果我勾选复选框并按enter键,则会显示以下消息: “KL15为:1”,如果我解开该框,它将显示“KL15为:0” 如果我注释掉名称空间,只需使用过程,它就可以正常工作 谁能告诉我为什么Tcl 在命名空间过程中未看到数组,但在过程中未看到命名空间,tcl,tk,Tcl,Tk,早上好 下面的代码显示了一个带有过程的名称空间,还有一个名为ds_out的数组 如果运行此代码并按enter按钮,则会出现错误: 错误:无法读取“ds_out(0)!:没有这样的变量 如果我勾选复选框并按enter键,则会显示以下消息: “KL15为:1”,如果我解开该框,它将显示“KL15为:0” 如果我注释掉名称空间,只需使用过程,它就可以正常工作 谁能告诉我为什么 namespace eval RELAY_SELECT { tk::labelframe .rs -text "Relay S
namespace eval RELAY_SELECT {
tk::labelframe .rs -text "Relay Selection"
array set ds_out {
0 0
1 0
}
proc create_RS_Labels {} {
tk::label .rs.kl15_lb -text "KL15" -justify center -width 5
}
proc create_RS_CBoxes {} {
tk::checkbutton .rs.kl15_cb -width 1 -height 1 -variable kl15_cb -command {if {$kl15_cb} {
set ds_out(0) 1
set ds_out(1) 1
} else {
set ds_out(0) 0
set ds_out(1) 0
} }
}
proc create_RS_enter_Button {} {
tk::button .rs.enter -borderwidth 1 -height 1 -text "Enter" -width 5 -command {if {$kl15_cb} {
set ds_out(0) 1
set ds_out(1) 1
puts "KL15 is: $ds_out(0)"
} else {
puts "KL15 is: $ds_out(0)"
set ds_out(0) 0
set ds_out(1) 0
}
}
}
proc create_RS_LabelFrame {} {
place .rs -x 10 -y 10
grid .rs.kl15_lb -row 0 -column 0
grid .rs.kl15_cb -row 0 -column 1
grid .rs.enter -row 12 -column 0 -columnspan 6
}
create_RS_Labels
create_RS_CBoxes
create_RS_enter_Button
create_RS_LabelFrame
}
变量作用域有问题 Tk命令回调始终在全局范围内进行计算。您的数组不在全局范围内(其他变量如
kl15_cb
是全局的,尽管您可能不希望它们是全局的)。这会很快变得非常混乱;强烈建议您为所有回调创建帮助程序。为了保持理智,这里是你的代码被修改成应该是什么样子;请特别注意注释代码>注释在那里
namespace eval RELAY_SELECT {
# Note! Declare variables in namespaces, always, to avoid an obscure misfeature!
variable kl15_cb 0
variable ds_out
array set ds_out {
0 0
1 0
}
proc create_RS_Labels {frame} {
tk::label $frame.kl15_lb -text "KL15" -justify center -width 5
}
proc create_RS_CBoxes {frame} {
# Note! Fully qualified variable name!
# Note! [namespace code] to make callback script!
tk::checkbutton $frame.kl15_cb -width 1 -height 1 -variable ::RELAY_SELECT::kl15_cb \
-command [namespace code { RS_CBox_callback }]
}
proc RS_CBox_callback {} {
# Note! [variable] with *ONE* argument to bring var into procedure scope
variable kl15_cb
variable ds_out
if {$kl15_cb} {
set ds_out(0) 1
set ds_out(1) 1
} else {
set ds_out(0) 0
set ds_out(1) 0
}
}
proc create_RS_enter_Button {frame} {
tk::button $frame.enter -borderwidth 1 -height 1 -text "Enter" -width 5 \
-command [namespace code { RS_enter_callback }]
}
proc RS_enter_callback {} {
variable kl15_cb
variable ds_out
if {$kl15_cb} {
set ds_out(0) 1
set ds_out(1) 1
puts "KL15 is: $ds_out(0)"
} else {
puts "KL15 is: $ds_out(0)"
set ds_out(0) 0
set ds_out(1) 0
}
}
proc create_RS_LabelFrame {frame} {
place $frame -x 10 -y 10
grid $frame.kl15_lb -row 0 -column 0
grid $frame.kl15_cb -row 0 -column 1
grid $frame.enter -row 12 -column 0 -columnspan 6
}
tk::labelframe .rs -text "Relay Selection"
create_RS_Labels .rs
create_RS_CBoxes .rs
create_RS_enter_Button .rs
create_RS_LabelFrame .rs
}
为了我自己的理智,我也按惯例缩进了所有内容。您是否建议使用-variable[namespace current]::kl15_cb
而不是在进程中硬编码命名空间名称?谢谢各位,我将对此进行研究。