Как создать массив для хранения значений нескольких автоматически сгенерированных флажков в Tk Tcl

У меня есть список объектов неизвестной длины, я хочу создать 2 списка флажков, в каждом списке по флажку для каждой строки списка. Мне также нужно иметь возможность добраться до флажков и проверить их значение.

Поскольку я не нашел способа получить значение флажка из его пути, я хотел создать глобальный массив, который будет содержать переменные для флажков, и попробовал следующее:

    global cb
    set i 0
    foreach port $ports {
    set to_cb    [checkbutton $to.cb_to_$i     -variable [list $cb(to$i)]   -text $port -command [list __sp_from_to_changed $from $to]]
    set from_cb  [checkbutton $from.cb_from_$i -variable [list $cb(from$i)] -text $port -command [list __sp_from_to_changed $from $to]]

    grid $to_cb   -row [expr $i + 2] -sticky nsew
    grid $from_cb -row [expr $i + 2] -sticky nsew
    incr i

Когда я получаю его, получаю ошибку can't read "cb(to0)": no such variable, как я могу назначить переменную внутри массива для флажка или, что еще лучше, есть ли способ получить текущее значение непосредственно из флажка без использования промежуточных переменных?


person SIMEL    schedule 29.07.2012    source источник


Ответы (1)


Флажки всегда должны быть привязаны к переменной (есть значение по умолчанию, но вы не хотите его использовать). Что вам нужно сделать, так это сгенерировать имя переменной, уникальное для каждой кнопки-флажка; здесь элемент массива является отличным выбором.

Так в чем проблема в вашем коде? Просто вы пытаетесь разыменовать переменные, поставив перед ними $; в отличие от некоторых других языков, Tcl всегда использует $ для обозначения «прочитать эту переменную» (за исключением регулярных выражений). Вам также не нужно заключать имя переменной в list; это было бы полезно, только если вы поместите его в сгенерированный скрипт. Вместо этого вам нужны такие строки:

set to_cb    [checkbutton $to.cb_to_$i     -variable cb(to$i)   -text $port \
        -command [list __sp_from_to_changed to $i]]
set from_cb  [checkbutton $from.cb_from_$i -variable cb(from$i) -text $port \
        -command [list __sp_from_to_changed from $i]]

Изменения здесь следующие:

  • Убрана дополнительная генерируемая сложность из значения опции -variable; голое имя элемента массива достаточно хорошо.
  • Аргументы обновлены до __sp_from_to_changed, чтобы они говорили о том, что на самом деле было изменено (первый аргумент теперь to или from, а второй — индекс; из него вы должны быть в состоянии построить все имена элементов, которые вам нужны, довольно тривиально).
  • Добавил обратную косую черту к этим длинным строкам, чтобы я мог разбить их для удобства чтения. :-)
person Donal Fellows    schedule 29.07.2012