TCL/TK 具有动态变量名称的单选按钮

TCL/TK Radiobutton with a Dynamic Variable Name in

我正在尝试在 TCL 中创建一个 TK GUI,使用户能够查看配置文件的当前值。此 GUI 将使用户能够通过 GUI 中的单选按钮将配置文件值更改为启用或禁用。我的配置文件将是可变长度的,因为可以添加附加项,并且我需要根据文件中的条目数构建 GUI。为了实现这一点,我试图在创建 GUI 时遍历配置文件,并为每组单选按钮使用一个变量,这些单选按钮可以为配置文件中的每个项目定义用户选择的值。

配置文件是一个简单的界面,可以使项目名称与启用 (E) 或禁用 (D) 值相关联。

Item1   D
Item2   E
Item3   D

下面是我必须为配置中的每个项目生成单选按钮的代码,可以选择启用、禁用或无更改。在这里,我试图为将存储单选按钮选择的每个项目创建动态变量。除了下面的当前代码外,我还尝试了其他变体,例如 -variable selItem${mVal}.

label .optionSelection.c${mVal}_1 -text $mVal
radiobutton .optionSelection.c${mVal}_2 -text "Enable" -variable selItem$mVal \
        -value "Enable" -justify left
radiobutton .optionSelection.c${mVal}_3 -text "Disable" -variable selItem$mVal \
        -value "Disable" -justify left
radiobutton .optionSelection.c${mVal}_4 -text "No Change" -variable selItem$mVal \
        -value "No Change" -justify left
label .optionSelection.c${mVal}_5 -text [dict get $configDict $mVal] \
        -textvariable curState${mVal}_5

为了获取 selItem$mVal (selItemItem1) 的值,我尝试使用下面的行获取要打印的值。我有不同的括号和方括号组合来创建变量 $selItemItem1,这样我就可以获得该项目的选定单选按钮的值。

puts "$mVal Variable is $selItem$mVal"

现在我只是想让变量打印出来,这样我就可以让它成为全局变量,并在代码中引用其他过程中的值。我对使用数组或字典作为单选按钮的变量进行了一些研究。这些方法看起来更简洁,但我无法找到有关如何通过变量设置数组或字典的示例。

使用的参考文献

  1. tcl: how to use the value of a variable to create a new variable
  2. TCL, How to name a variable that includes another variable
  3. https://www.tutorialspoint.com/tcl-tk/tcl_variables.htm

您肯定想在这里使用数组。要使用数组,只需使用 arrayname($index) 作为变量名,并使用 $arrayname($index) 访问数组中的值。

下面是关于如何编写配置屏幕的简单概念证明。我在配置文件中使用 = 符号将标签与值分开,而不是 space。如果该值包含 = 符号,此代码将无法正常工作。

我还添加了一些描述性名称以显示给用户。

这可以扩展以允许其他类型的配置选项,肯定会更改以提供更好的用户体验等。

package require Tk

proc init { } {
  global config
  global descriptions

  set descriptions(Item1) {Item 1 Label}
  set descriptions(Item2) {Config B}
  set descriptions(Item3) {Item 3}
  foreach name [array names descriptions] {
    set config($name) D
  }
}

proc displayOptions { } {
  global config
  global descriptions

  ttk::frame .optionSel
  ttk::label .optionSel.empty -text {}
  ttk::label .optionSel.head_on -text On
  ttk::label .optionSel.head_off -text Off
  grid .optionSel
  grid .optionSel.empty .optionSel.head_on .optionSel.head_off

  set fh [open t.txt r]
  while { [gets $fh line] >= 0 } {
    lassign [split $line =] name value
    set config($name) $value
  }
  close $fh

  foreach name [array names descriptions] {
    ttk::label .optionSel.lab${name} -text $descriptions($name)
    ttk::radiobutton .optionSel.c${name}_on -value E -variable config($name)
    ttk::radiobutton .optionSel.c${name}_off -value D -variable config($name)
    grid .optionSel.lab${name} .optionSel.c${name}_on .optionSel.c${name}_off \
        -sticky w
  }
  ttk::button .optionSel.save -text { Save } -command ::saveOptions
  grid .optionSel.save
}

proc saveOptions { } {
  global descriptions
  global config

  set fh [open t.txt w]
  foreach name [array names descriptions] {
    puts $fh "$name=$config($name)"
  }
  close $fh
}

init
displayOptions