Радио кнопки, ведущие себя как один - PullRequest
0 голосов
/ 09 сентября 2018

Я строю диалог из базы данных и использую ключ в качестве переменной для переключателей. Всякий раз, когда я нажимаю переключатель, все кнопки в одном столбце меняются. В словаре есть переменные верхнего уровня с именами

#!/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 ]

0 голосов
/ 09 сентября 2018

Проблема в «общей» переменной 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
        }

Надеюсь, это поможет вам,

Saludos!

0 голосов
/ 09 сентября 2018

Опция -variable виджетов относится к глобальной переменной. Так что это в другой области, чем debvar в вашей процедуре DisplayOptions. У них бывает одно и то же имя, но в остальном они вообще не имеют отношения.

Используя одну глобальную переменную для всех радиокнопок, они все работают как одна группа. Чтобы иметь несколько групп радиокнопок, вы должны использовать разные глобальные переменные для каждой группы, как вы это делали с версией r_ $ row. Обратите внимание, что опять-таки локальная переменная r_ $ row в вашем proc не имеет отношения к переменной r_ $ row, которую вы используете для виджетов.

На самом деле было бы лучше использовать другую (более простую) локальную переменную, потому что if { r_$row == 0 } всегда будет ложным, и слишком сложно получить значение переменной, имя которой построено как r_ $ row.

...