代码之家  ›  专栏  ›  技术社区  ›  cup

单选按钮作为一个

  •  1
  • cup  · 技术社区  · 6 年前

    #!/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别名)不会变。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Schelte Bron    6 年前

    小部件的-variable选项引用一个全局变量。所以这与DisplayOptions过程中的debvar在不同的范围内。他们碰巧同名,但在其他方面根本没有关系。

    通过对所有单选按钮使用相同的全局变量,它们都作为一个组工作。要有多组单选按钮,您必须为每个组使用不同的全局变量,就像您在r琰$row版本中所做的那样。请再次注意,proc中的r\u$row局部变量与用于小部件的r\u$row变量没有关系。

    实际上,最好使用一个不同的(更简单的)局部变量,因为 if { r_$row == 0 } 将始终为false,并且获取一个名称被构造为r_u$row的变量的值过于复杂。

        2
  •  1
  •   L. Alejandro M.    6 年前

    问题出在“shared”变量中 德瓦 . 你忘了对每一行应用相同的方法,在这种方式下,你可以做例如。。。

            # 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
            }
    

    我希望这对你有帮助,