Создайте поле с несколькими входами, используя цикл for в tcl/tk

Привет, у меня есть целочисленное значение, и на его основе я должен создать поля ввода в графическом интерфейсе tcl/tk. Итак, я сделал что-то вроде этого:

    set frame1 [::hwt::LabeledFrame [::hwt::WindowRecess editThicknessWindow].frame1 "Current List: " \
                                                        -expand 0 -relief flat -anchor e -side top -pady 15]

    for {set i 0} {$i < $length_Thickness} {incr i} {
        set Entry_No_$i [::hwt::AddEntry $frame1.Entry_No_[eval $i] label "List Values_$i :" labelwidth 15 \
          entryWidth 10 anchor nw validate real text [namespace current]::arr_attribOptionsValue(Thickness)[$i] state normal \
          withoutPacking -textvariable [namespace current]::lst_Value[$i] ]
          pack $Entry_No_[eval $i] -side top -anchor nw -padx 10 -pady 10
    }       

Допустим, у меня есть целое число 3, тогда мне нужно создать 3 поля ввода. У меня есть список «arr_attribOptionsValue (Thickness)» с 3 значениями, поэтому я хочу, чтобы значения из списка были заполнены в полях ввода. Поскольку я новичок в tcl/tk, поэтому не уверен, что синтаксис правильный или я что-то упустил. Я запутался, как будто я создаю переменную tk Entry_No_$i, а в пакете я использую $Entry_No_[eval $i], так что эти два будут ссылаться на одно и то же значение или это неправильный синтаксис.


person Puneet Mittal    schedule 17.12.2012    source источник


Ответы (1)


Во-первых, если вы создаете такие переменные, как $Entry_No_[eval $i], то я действительно думаю, что вы делаете это неправильно. Такие составные переменные на самом деле гораздо проще сделать в виде элементов массива, таких как Entry_No($i), без eval, чтобы все запутать (или $Entry_No($i), чтобы читать из элемента, а не называть его).

Во-вторых, [namespace current]::arr_attribOptionsValue(Thickness)[$i] с большей вероятностью будет неправильным, тем более что $i будет целым числом. Вы не можете обращаться к такому элементу списка (не предполагалось, что это должно быть возможным, но это точно не произойдет в ближайшие несколько месяцев, и уж точно не в сочетание с таким массивом). Вместо этого простейшим механизмом является использование другого массива, который вы заполняете из исходного списка, и использование трассировки для обратной связи, если это необходимо. (Трассы — это более продвинутый метод; задайте другой вопрос, если они вам нужны.) Заполнение рабочего массива из списка может быть выполнено следующим образом:

set i 0
foreach item $arr_attribOptions(Thickness) {
    set varname arr_attribOptions(Thickness,$i)
    set $varname $item
    incr i
}

Да, вы можете хранить имя переменной в переменной. (При чтении используйте [set $varname] для двойного разыменования.)

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

В-четвертых, используйте variable (или upvar, или namespace upvar), чтобы не использовать полностью определенные переменные.


В целом, мы можем использовать эти методы вместе, чтобы получить что-то вроде этого:

set frame1 [::hwt::LabeledFrame [::hwt::WindowRecess editThicknessWindow].frame1 "Current List: " \
        -expand 0 -relief flat -anchor e -side top -pady 15]

namespace upvar [namespace current] \
        arr_attribOptions attribs arr_values values lst_Value valueList
set i 0
foreach item $attribs(Thickness) {
    set attribs(Thickness,$i) $item
    set values($i) [lindex $valueList $i]
    incr i
}

for {set i 0} {$i < $length_Thickness} {incr i} {
    set Entry_No($i) [::hwt::AddEntry $frame1.entry_No_$i label "List Values_$i :" labelwidth 15 \
            entryWidth 10 anchor nw validate real text arr_attribOptions(Thickness,$i) state normal \
            withoutPacking -textvariable [namespace current]::arr_values($i)]
    pack $Entry_No($i) -side top -anchor nw -padx 10 -pady 10
}

Я не уверен, что уже выявил все проблемы (и большинство программистов Tcl не используют префиксы венгерского типа в именах переменных), но теперь это намного ближе к идиоматике.

person Donal Fellows    schedule 17.12.2012
comment
Команда ::hwt::AddEntry выглядит на мой взгляд так, что над ней нужно еще поработать, но у меня нет времени делать это самому… - person Donal Fellows; 18.12.2012
comment
Спасибо за помощь, Донал, команда ::hwt::AddEntry не что иное, как команда AddEntry tk. Думаю, это просто пространство имен, с которым мы его использовали. - person Puneet Mittal; 19.12.2012