单选按钮作为一个
Radio buttons behaving as one
我正在从数据库构建一个对话框,并将键用作单选按钮的变量。每当我单击单选按钮时,同一列中的所有按钮都会更改。有字典中名称的顶级变量
#!/usr/bin/tclsh
package require Tk
variable dict_config
set dict_config [dict create]
dict set dict_config config_single_step { 0 "Single step" "Single step" "Run" }
dict set dict_config config_load { 0 "Load" "No load on startup" "Load oad on startup" }
dict set dict_config config_news { 0 "News" "No news" "News Feed" }
# Callback to set the value
proc SetValue { ix val } {
puts "Setting $ix to $val"
variable dict_config
set list_item [dict get $dict_config $ix]
dict set dict_config $ix [lreplace $list_item 0 0 $val]
}
proc todo {} {
puts "Coming soon to a screen near you"
}
proc DisplayOptions { dict_config } {
set row 0
dict for { ix list_item } $dict_config {
# Extract data from the list
set lab [lindex $list_item 1]
set zero [lindex $list_item 2]
set one [lindex $list_item 3]
incr row
# set dummy variable so the radio buttons respond correctly.
set $ix [lindex $list_item 0]
upvar 0 $ix debvar
# Create widgets
label .lab_$row -text $lab
radiobutton .zero_$row -text $zero -variable debvar -value 0 -command "SetValue $ix 0"
radiobutton .one_$row -text $one -variable debvar -value 1 -command "SetValue $ix 1"
if { $debvar == 0 } {
.zero_$row select
} else {
.one_$row select
}
# Layout widgets
grid .lab_$row -sticky e -row $row -column 0
grid .zero_$row -sticky w -row $row -column 1
grid .one_$row -sticky w -row $row -column 2
}
incr row
grid [button .butSave -text "Save" -command "todo"] -row $row -column 0
}
# Let the user change them
DisplayOptions $dict_config
我也试过 $debvar - 同样的事情发生了。如果我将循环体更改为
,我可以让它工作
# Extract data from the list
set lab [lindex $list_item 1]
set zero [lindex $list_item 2]
set one [lindex $list_item 3]
incr row
# set dummy variable so the radio buttons respond correctly.
set r_$row [lindex $list_item 0]
# Create widgets
label .lab_$row -text $lab
radiobutton .zero_$row -text $zero -variable r_$row -value 0 -command "SetValue $ix 0"
radiobutton .one_$row -text $one -variable r_$row -value 1 -command "SetValue $ix 1"
if { r_$row == 0 } {
.zero_$row select
} else {
.one_$row select
}
# Layout widgets
grid .lab_$row -sticky e -row $row -column 0
grid .zero_$row -sticky w -row $row -column 1
grid .one_$row -sticky w -row $row -column 2
我只是想知道为什么 r_$row 起作用,即按钮不会像一个按钮那样改变,但是 $debvar,它是一个 upvar 别名却不会。
widgets的-variable选项是指一个全局变量。所以这与 DisplayOptions proc 中的 debvar 范围不同。他们恰好同名,除此之外毫无关系。
通过对所有单选按钮使用相同的全局变量,它们都作为一个组工作。要有几组单选按钮,您必须为每组使用不同的全局变量,就像您对 r_$row 版本所做的那样。请再次注意,您的 proc 中的 r_$row 局部变量与您用于小部件的 r_$row 变量无关。
实际上您最好使用不同的(更简单的)局部变量,因为 if { r_$row == 0 }
将始终为假,并且获取名称构造为 r_$row 的变量的值过于复杂。
问题出在 "shared" 变量 debvar 中。你忘了对每一行应用相同的方法,这样,你可以做例如......
# set dummy variable so the radio buttons respond correctly.
set $ix [lindex $list_item 0]
upvar 0 $ix debvar_$row;# <-- Here add the row number
# Create widgets
label .lab_$row -text $lab
;#<-- Below these two lines are changed too
radiobutton .zero_$row -text $zero -variable debvar_$row -value 0 -command "SetValue $ix 0"
radiobutton .one_$row -text $one -variable debvar_$row -value 1 -command "SetValue $ix 1"
;#<-- Finally you must use a way of dereferencing in order to use each debvar
if { [set debvar_$row] == 0 } {
.zero_$row select
} else {
.one_$row select
}
希望对你有所帮助,
你好!
我正在从数据库构建一个对话框,并将键用作单选按钮的变量。每当我单击单选按钮时,同一列中的所有按钮都会更改。有字典中名称的顶级变量
#!/usr/bin/tclsh
package require Tk
variable dict_config
set dict_config [dict create]
dict set dict_config config_single_step { 0 "Single step" "Single step" "Run" }
dict set dict_config config_load { 0 "Load" "No load on startup" "Load oad on startup" }
dict set dict_config config_news { 0 "News" "No news" "News Feed" }
# Callback to set the value
proc SetValue { ix val } {
puts "Setting $ix to $val"
variable dict_config
set list_item [dict get $dict_config $ix]
dict set dict_config $ix [lreplace $list_item 0 0 $val]
}
proc todo {} {
puts "Coming soon to a screen near you"
}
proc DisplayOptions { dict_config } {
set row 0
dict for { ix list_item } $dict_config {
# Extract data from the list
set lab [lindex $list_item 1]
set zero [lindex $list_item 2]
set one [lindex $list_item 3]
incr row
# set dummy variable so the radio buttons respond correctly.
set $ix [lindex $list_item 0]
upvar 0 $ix debvar
# Create widgets
label .lab_$row -text $lab
radiobutton .zero_$row -text $zero -variable debvar -value 0 -command "SetValue $ix 0"
radiobutton .one_$row -text $one -variable debvar -value 1 -command "SetValue $ix 1"
if { $debvar == 0 } {
.zero_$row select
} else {
.one_$row select
}
# Layout widgets
grid .lab_$row -sticky e -row $row -column 0
grid .zero_$row -sticky w -row $row -column 1
grid .one_$row -sticky w -row $row -column 2
}
incr row
grid [button .butSave -text "Save" -command "todo"] -row $row -column 0
}
# Let the user change them
DisplayOptions $dict_config
我也试过 $debvar - 同样的事情发生了。如果我将循环体更改为
,我可以让它工作 # Extract data from the list
set lab [lindex $list_item 1]
set zero [lindex $list_item 2]
set one [lindex $list_item 3]
incr row
# set dummy variable so the radio buttons respond correctly.
set r_$row [lindex $list_item 0]
# Create widgets
label .lab_$row -text $lab
radiobutton .zero_$row -text $zero -variable r_$row -value 0 -command "SetValue $ix 0"
radiobutton .one_$row -text $one -variable r_$row -value 1 -command "SetValue $ix 1"
if { r_$row == 0 } {
.zero_$row select
} else {
.one_$row select
}
# Layout widgets
grid .lab_$row -sticky e -row $row -column 0
grid .zero_$row -sticky w -row $row -column 1
grid .one_$row -sticky w -row $row -column 2
我只是想知道为什么 r_$row 起作用,即按钮不会像一个按钮那样改变,但是 $debvar,它是一个 upvar 别名却不会。
widgets的-variable选项是指一个全局变量。所以这与 DisplayOptions proc 中的 debvar 范围不同。他们恰好同名,除此之外毫无关系。
通过对所有单选按钮使用相同的全局变量,它们都作为一个组工作。要有几组单选按钮,您必须为每组使用不同的全局变量,就像您对 r_$row 版本所做的那样。请再次注意,您的 proc 中的 r_$row 局部变量与您用于小部件的 r_$row 变量无关。
实际上您最好使用不同的(更简单的)局部变量,因为 if { r_$row == 0 }
将始终为假,并且获取名称构造为 r_$row 的变量的值过于复杂。
问题出在 "shared" 变量 debvar 中。你忘了对每一行应用相同的方法,这样,你可以做例如......
# set dummy variable so the radio buttons respond correctly.
set $ix [lindex $list_item 0]
upvar 0 $ix debvar_$row;# <-- Here add the row number
# Create widgets
label .lab_$row -text $lab
;#<-- Below these two lines are changed too
radiobutton .zero_$row -text $zero -variable debvar_$row -value 0 -command "SetValue $ix 0"
radiobutton .one_$row -text $one -variable debvar_$row -value 1 -command "SetValue $ix 1"
;#<-- Finally you must use a way of dereferencing in order to use each debvar
if { [set debvar_$row] == 0 } {
.zero_$row select
} else {
.one_$row select
}
希望对你有所帮助,
你好!