Tcl 变量中存储了什么?
根据这个问题 我编写了一个小 gui 来获取命令行 C 程序的选项,并将它们传递给已经设置为处理它们的所述 C 程序。 它的显示就像我想要的那样。
但是,我想验证变量中存储的值是否正确。 打印出这些值让我很伤心(由于一些硬件问题,我现在无法在体内进行测试)。 我缺少什么?
- 在变量名称前面加上“$”会得到“$variableName”,而不是变量的值。
- 将这些变量添加到数组并调用 array get arr 应该打印索引和数组值; 我得到变量名。
- 我尝试了 pathName
cget
option,但显然-value
不是一个选项,并且忽略该选项不会不要给我有效选项的列表。
这是所有不起作用的各种代码(来自选项#1,这是最直接的方法;其他只是我尝试解决方法)。 他们都生产 错误如下:“无法读取“::”:没有这样的变量”或“无法读取 “比色”:没有这样的变量”。
#!/opt/ActiveTcl-8.5/bin/wish8.5
wm title . "Gretag"
ttk::frame .f -borderwidth 5 -relief sunken -padding "5 10"
# next line part of the "puts" tests at the bottom
global colorimetric
ttk::label .f.dataLabel -text "Data Type"
ttk::label .f.colorimetricLabel -text "Colorimetric"
ttk::checkbutton .f.colorimetric -onvalue "-c" -offvalue "" -command getFilename1
ttk::label .f.spectralLabel -text "Spectral"
ttk::checkbutton .f.spectral -onvalue "-s" -offvalue "" -command getFilename2
ttk::label .f.gretagNumLabel -text "Gretag #"
ttk::label .f.gretagLabel0 -text "1"
ttk::radiobutton .f.gretagRadio0 -variable gretagNum -value "/dev/ttyS0"
ttk::label .f.gretagLabel1 -text "2"
ttk::radiobutton .f.gretagRadio1 -variable gretagNum -value "/dev/ttyS1"
ttk::label .f.gretagLabel2 -text "3"
ttk::radiobutton .f.gretagRadio2 -variable gretagNum -value "/dev/ttyS2"
ttk::label .f.gretagLabel3 -text "4"
ttk::radiobutton .f.gretagRadio3 -variable gretagNum -value "/dev/ttyS3"
ttk::label .f.gretagLabel4 -text "5"
ttk::radiobutton .f.gretagRadio4 -variable gretagNum -value "/dev/ttyS4"
ttk::label .f.sampleSize -text "Sample Size"
ttk::label .f.samplex -text "X"
ttk::label .f.sampley -text "Y"
ttk::entry .f.x -textvariable x -width 5
ttk::entry .f.y -textvariable y -width 5
ttk::label .f.filterLabel -text "Filter Type"
ttk::label .f.filterLabel0 -text "D50"
ttk::radiobutton .f.filterRadio0 -variable filter -value "-d50"
ttk::label .f.filterLabel1 -text "D65"
ttk::radiobutton .f.filterRadio1 -variable filter -value "-d65"
ttk::label .f.filterLabel2 -text "Unfiltered"
ttk::radiobutton .f.filterRadio2 -variable filter -value "-U"
ttk::label .f.filterLabel3 -text "Polarized"
ttk::radiobutton .f.filterRadio3 -variable filter -value "-p"
ttk::label .f.baudLabel -text "Baud Rate"
ttk::label .f.baudLabel0 -text "4800"
ttk::radiobutton .f.baudRadio0 -variable baud -value "B4800"
ttk::label .f.baudLabel1 -text "9600"
ttk::radiobutton .f.baudRadio1 -variable baud -value "B9600"
ttk::label .f.baudLabel2 -text "19200"
ttk::radiobutton .f.baudRadio2 -variable baud -value "B19200"
ttk::label .f.baudLabel3 -text "38400"
ttk::radiobutton .f.baudRadio3 -variable baud -value "B38400"
ttk::label .f.baudLabel4 -text "57600"
ttk::radiobutton .f.baudRadio4 -variable baud -value "B57600"
ttk::button .f.submitBtn -text "Submit" -command finish
grid columnconfigure . 0 -weight 1
grid rowconfigure . 0 -weight 1
grid .f -column 0 -row 0 -columnspan 11 -rowspan 5
grid .f.dataLabel -column 0 -row 0 -sticky we
grid .f.colorimetricLabel -column 1 -row 0 -sticky e
grid .f.colorimetric -column 2 -row 0 -sticky w
grid .f.spectralLabel -column 3 -row 0 -sticky e
grid .f.spectral -column 4 -row 0 -sticky w
grid .f.gretagNumLabel -column 0 -row 1 -sticky we
grid .f.gretagLabel0 -column 1 -row 1 -sticky e
grid .f.gretagRadio0 -column 2 -row 1 -sticky w
grid .f.gretagLabel1 -column 3 -row 1 -sticky e
grid .f.gretagRadio1 -column 4 -row 1 -sticky w
grid .f.gretagLabel2 -column 5 -row 1 -sticky e
grid .f.gretagRadio2 -column 6 -row 1 -sticky w
grid .f.gretagLabel3 -column 7 -row 1 -sticky e
grid .f.gretagRadio3 -column 8 -row 1 -sticky w
grid .f.gretagLabel4 -column 9 -row 1 -sticky e
grid .f.gretagRadio4 -column 10 -row 1 -sticky w
grid .f.sampleSize -column 0 -row 2 -sticky we
grid .f.samplex -column 1 -row 2 -sticky e
grid .f.x -column 2 -row 2 -sticky w
grid .f.sampley -column 3 -row 2 -sticky e
grid .f.y -column 4 -row 2 -sticky w
grid .f.filterLabel -column 0 -row 3 -sticky we
grid .f.filterLabel0 -column 1 -row 3 -sticky e
grid .f.filterRadio0 -column 2 -row 3 -sticky w
grid .f.filterLabel1 -column 3 -row 3 -sticky e
grid .f.filterRadio1 -column 4 -row 3 -sticky w
grid .f.filterLabel2 -column 5 -row 3 -sticky e
grid .f.filterRadio2 -column 6 -row 3 -sticky w
grid .f.filterLabel3 -column 7 -row 3 -sticky e
grid .f.filterRadio3 -column 8 -row 3 -sticky w
grid .f.baudLabel -column 0 -row 4 -sticky we
grid .f.baudLabel0 -column 1 -row 4 -sticky e
grid .f.baudRadio0 -column 2 -row 4 -sticky w
grid .f.baudLabel1 -column 3 -row 4 -sticky e
grid .f.baudRadio1 -column 4 -row 4 -sticky w
grid .f.baudLabel2 -column 5 -row 4 -sticky e
grid .f.baudRadio2 -column 6 -row 4 -sticky w
grid .f.baudLabel3 -column 7 -row 4 -sticky e
grid .f.baudRadio3 -column 8 -row 4 -sticky w
grid .f.baudLabel4 -column 9 -row 4 -sticky e
grid .f.baudRadio4 -column 10 -row 4 -sticky w
grid .f.submitBtn -column 1 -row 5 -columnspan 7 -sticky we
foreach w [winfo children .f] {grid configure $w -padx 5 -pady 5}
focus .f.colorimetric
.f.colorimetric state selected
.f.filterRadio1 state selected
.f.baudRadio1 state selected
bind . <Return> {finish}
proc getFilename1 {} {
set filename1 [tk_getSaveFile]
}
proc getFilename2 {} {
set filename2 [tk_getSaveFile]
}
proc finish {} {
.f.x insert 0 "-x"
.f.y insert 0 "-y"
# Pick one
# puts $colorimetric
# puts colorimetric
# puts "$colorimetric"
# puts $::colorimetric
# puts .f.colorimetric
# puts $.f.colorimetric
# puts $::.f.colorimetric
# puts "$::colorimetric"
exec ./gretag .f.colorimetric filename1 .f.spectral filename2 .f.gretagNum .f.x .f.y .f.filter .f.baud
}
编辑: 我已经发布了所有代码,而不仅仅是部分代码,在倒数第二行中是我尝试过的选项 #1 中的各种语法,以便在变量值传递到下一个程序之前查看它们的值。 这些都不起作用,我不明白为什么或如何解决它。 我希望另一双眼睛能发现问题所在。
Pursuant to the advice given in this question I have written a little gui to take the options for a command line C program and pass them on to said C program which is already set up to process them. It displays just like I wanted.
However, I would like to verify that the values stored in the variables are correct. Getting the values to print out is giving me a lot of grief (I can't test in vivo right now due to some hardware issues). What am I missing?
- Prepending the variable name with '$' gives me '$variableName' rather than the value of the variable.
- Adding these variables to an array and calling
array get arr
is supposed to print the index and the array value; I get variable names. - I tried pathName
cget
option, but apparently-value
isn't an option, and leaving off the option doesn't give me a list of valid options.
Here's all the code with the various things that didn't work (from option #1, which is the most straightforward way; the others were just me trying workarounds). They all produce
errors along the lines of: "can't read "::": no such variable" or "can't read
"colorimetric": no such variable".
#!/opt/ActiveTcl-8.5/bin/wish8.5
wm title . "Gretag"
ttk::frame .f -borderwidth 5 -relief sunken -padding "5 10"
# next line part of the "puts" tests at the bottom
global colorimetric
ttk::label .f.dataLabel -text "Data Type"
ttk::label .f.colorimetricLabel -text "Colorimetric"
ttk::checkbutton .f.colorimetric -onvalue "-c" -offvalue "" -command getFilename1
ttk::label .f.spectralLabel -text "Spectral"
ttk::checkbutton .f.spectral -onvalue "-s" -offvalue "" -command getFilename2
ttk::label .f.gretagNumLabel -text "Gretag #"
ttk::label .f.gretagLabel0 -text "1"
ttk::radiobutton .f.gretagRadio0 -variable gretagNum -value "/dev/ttyS0"
ttk::label .f.gretagLabel1 -text "2"
ttk::radiobutton .f.gretagRadio1 -variable gretagNum -value "/dev/ttyS1"
ttk::label .f.gretagLabel2 -text "3"
ttk::radiobutton .f.gretagRadio2 -variable gretagNum -value "/dev/ttyS2"
ttk::label .f.gretagLabel3 -text "4"
ttk::radiobutton .f.gretagRadio3 -variable gretagNum -value "/dev/ttyS3"
ttk::label .f.gretagLabel4 -text "5"
ttk::radiobutton .f.gretagRadio4 -variable gretagNum -value "/dev/ttyS4"
ttk::label .f.sampleSize -text "Sample Size"
ttk::label .f.samplex -text "X"
ttk::label .f.sampley -text "Y"
ttk::entry .f.x -textvariable x -width 5
ttk::entry .f.y -textvariable y -width 5
ttk::label .f.filterLabel -text "Filter Type"
ttk::label .f.filterLabel0 -text "D50"
ttk::radiobutton .f.filterRadio0 -variable filter -value "-d50"
ttk::label .f.filterLabel1 -text "D65"
ttk::radiobutton .f.filterRadio1 -variable filter -value "-d65"
ttk::label .f.filterLabel2 -text "Unfiltered"
ttk::radiobutton .f.filterRadio2 -variable filter -value "-U"
ttk::label .f.filterLabel3 -text "Polarized"
ttk::radiobutton .f.filterRadio3 -variable filter -value "-p"
ttk::label .f.baudLabel -text "Baud Rate"
ttk::label .f.baudLabel0 -text "4800"
ttk::radiobutton .f.baudRadio0 -variable baud -value "B4800"
ttk::label .f.baudLabel1 -text "9600"
ttk::radiobutton .f.baudRadio1 -variable baud -value "B9600"
ttk::label .f.baudLabel2 -text "19200"
ttk::radiobutton .f.baudRadio2 -variable baud -value "B19200"
ttk::label .f.baudLabel3 -text "38400"
ttk::radiobutton .f.baudRadio3 -variable baud -value "B38400"
ttk::label .f.baudLabel4 -text "57600"
ttk::radiobutton .f.baudRadio4 -variable baud -value "B57600"
ttk::button .f.submitBtn -text "Submit" -command finish
grid columnconfigure . 0 -weight 1
grid rowconfigure . 0 -weight 1
grid .f -column 0 -row 0 -columnspan 11 -rowspan 5
grid .f.dataLabel -column 0 -row 0 -sticky we
grid .f.colorimetricLabel -column 1 -row 0 -sticky e
grid .f.colorimetric -column 2 -row 0 -sticky w
grid .f.spectralLabel -column 3 -row 0 -sticky e
grid .f.spectral -column 4 -row 0 -sticky w
grid .f.gretagNumLabel -column 0 -row 1 -sticky we
grid .f.gretagLabel0 -column 1 -row 1 -sticky e
grid .f.gretagRadio0 -column 2 -row 1 -sticky w
grid .f.gretagLabel1 -column 3 -row 1 -sticky e
grid .f.gretagRadio1 -column 4 -row 1 -sticky w
grid .f.gretagLabel2 -column 5 -row 1 -sticky e
grid .f.gretagRadio2 -column 6 -row 1 -sticky w
grid .f.gretagLabel3 -column 7 -row 1 -sticky e
grid .f.gretagRadio3 -column 8 -row 1 -sticky w
grid .f.gretagLabel4 -column 9 -row 1 -sticky e
grid .f.gretagRadio4 -column 10 -row 1 -sticky w
grid .f.sampleSize -column 0 -row 2 -sticky we
grid .f.samplex -column 1 -row 2 -sticky e
grid .f.x -column 2 -row 2 -sticky w
grid .f.sampley -column 3 -row 2 -sticky e
grid .f.y -column 4 -row 2 -sticky w
grid .f.filterLabel -column 0 -row 3 -sticky we
grid .f.filterLabel0 -column 1 -row 3 -sticky e
grid .f.filterRadio0 -column 2 -row 3 -sticky w
grid .f.filterLabel1 -column 3 -row 3 -sticky e
grid .f.filterRadio1 -column 4 -row 3 -sticky w
grid .f.filterLabel2 -column 5 -row 3 -sticky e
grid .f.filterRadio2 -column 6 -row 3 -sticky w
grid .f.filterLabel3 -column 7 -row 3 -sticky e
grid .f.filterRadio3 -column 8 -row 3 -sticky w
grid .f.baudLabel -column 0 -row 4 -sticky we
grid .f.baudLabel0 -column 1 -row 4 -sticky e
grid .f.baudRadio0 -column 2 -row 4 -sticky w
grid .f.baudLabel1 -column 3 -row 4 -sticky e
grid .f.baudRadio1 -column 4 -row 4 -sticky w
grid .f.baudLabel2 -column 5 -row 4 -sticky e
grid .f.baudRadio2 -column 6 -row 4 -sticky w
grid .f.baudLabel3 -column 7 -row 4 -sticky e
grid .f.baudRadio3 -column 8 -row 4 -sticky w
grid .f.baudLabel4 -column 9 -row 4 -sticky e
grid .f.baudRadio4 -column 10 -row 4 -sticky w
grid .f.submitBtn -column 1 -row 5 -columnspan 7 -sticky we
foreach w [winfo children .f] {grid configure $w -padx 5 -pady 5}
focus .f.colorimetric
.f.colorimetric state selected
.f.filterRadio1 state selected
.f.baudRadio1 state selected
bind . <Return> {finish}
proc getFilename1 {} {
set filename1 [tk_getSaveFile]
}
proc getFilename2 {} {
set filename2 [tk_getSaveFile]
}
proc finish {} {
.f.x insert 0 "-x"
.f.y insert 0 "-y"
# Pick one
# puts $colorimetric
# puts colorimetric
# puts "$colorimetric"
# puts $::colorimetric
# puts .f.colorimetric
# puts $.f.colorimetric
# puts $::.f.colorimetric
# puts "$::colorimetric"
exec ./gretag .f.colorimetric filename1 .f.spectral filename2 .f.gretagNum .f.x .f.y .f.filter .f.baud
}
Edit:
I've posted all the code rather than just part, and in the next to last line are the various syntaxes from option #1 that I've tried in order to view the values of the variables before they're passed to the next program. None of these are working and I don't understand why or how to fix it. I'm hoping another set of eyes will catch what's wrong.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我不确定你想做什么,如果你最终打印变量名称而不是变量内容,请使用set命令作为函数:
设置内容“ hello"
set blah content
如果您这样做:
..您将获得 blah 变量的内容,即内容。
要通过 blah 获取变量 content 的内容,请使用以下命令:
I'm not sure what you want to do, put if you end put printing the variable name and not the variable content, use the set command as function:
set content "hello"
set blah content
if you do:
.. you get the content of the blah variable, which is content.
To get the content of the variable content via blah, use the following:
只要记住这条规则,你就永远会做对:
尝试用 [set foo] 重写你的代码,它会起作用。
特别地,
被替换为
Just remember this rule and you will always get it right:
Try rewriting your code with [set foo] and it will work.
In particular,
is replaced by
变量基础知识
正如其他人所指出的,令人困惑的 to $ 或 not to $ 表示法可以通过以下规则进行简化。
当您开始考虑其中的所有内容时,它可能会变得更加混乱Tcl 作为字符串(实际上不是,但足够接近),因此您可以将一个变量的名称存储在另一个变量中,并通过引用恢复其值。
这里,符号
set $foo
在步骤中进行评估 - 首先$foo
产生其值hi
,然后是set
表达式(当不带第三个参数运行时)尝试返回变量hi
中保存的值。 这失败了。 符号set $bar
采取相同的步骤,但这次set
可以对bar
的值进行操作,即foo,因此返回
foo
的值,即hi
。 (链接到“set”API)初始化
您在此过程中遇到的一个问题脚本是初始化。 在 Tcl 中,变量在被赋值之前并不存在。 这显然就是为什么上面的
set $foo
尝试不起作用的原因,因为没有变量hi
。在脚本的顶部,您尝试声明一个变量,
但这不起作用,因为您已经在全局范围内操作。 全局“除非在过程主体的上下文中执行,否则没有任何效果”。 (链接到“global”API) 您实际上必须使用 < code>set 命令来初始化变量。 这就是为什么您尝试在
proc finish
中打印colorimetric
都不起作用。范围
此脚本中遇到的另一个问题是范围,特别是混合全局范围和过程/局部范围。 你是对的,如果你正确地初始化了
colorimetric
,那么代码就会起作用。 实现此目的的另一种方法是使用
“我的解决方案”
,我想展示我的解决方案。 我承认我已经移动了很多代码,并且我将简短地解释我实现了哪些更改以使其更加简洁。
更改讨论
1. 我所做的第一个更改是在
ttk::checkbutton
和ttk 上使用
。 当然,使用额外的标签可以让您将文本放置在按钮之前,但这样做是非标准的,并且需要更多代码。-text
选项: :单选按钮变成
2。 接下来,我利用这两个检查按钮之间的相似性将创建抽象为 foreach。 (我在工作的 Tcl 代码中一直这样做。)这会生成更容易阅读的代码,并允许您添加/删除/交换小部件的名称和标签。 它会产生稍微多一点但更加通用的代码。
变为
3。 下一个更改是将
getFilename1
和getFilename2
合并到单个getFilename
过程中。 我们可以将参数传递给这个函数来确定谁在调用它。 我使用list
命令生成对此新函数的调用。 (链接到“list”API)我也开始结合你的< code>grid 命令插入小部件代码本身。 这里 mygrid 保存了 GUI 中每行需要网格化的内容的列表,然后在每个部分的末尾进行评估以动态传播 GUI。 (链接到“grid”API)
之前的代码得到了最终修订并变为,
然后可以评估
grid
命令,并在每次使用后清除mygrid
变量!4. 如果您一直在注意的话,我还在您的
ttk::checkbutton
中添加了一个-variable
选项,此时开始存储全局变量 CONF 中的按钮状态。 这是一个很大的变化。Tk 喜欢污染您的全局命名空间,反击是一个很好的做法。 我通常将所有配置状态放在一个全局数组中,并将其设置在代码的顶部,以便任何人都可以进入并更改代码的默认状态,而无需深入研究它或执行搜索/替换调用或类似的操作那。 这只是一个好的实践,所以无论你有一个变量,我都会将其移动到
CONF
中,并将CONF
移到顶部。5. 接下来,我将这些更改传播到您的代码中。 几乎所有的小部件创建都容易受到这些修订的影响。 关于小部件的创建,这有时会使独立的代码部分变得更大。 但它也允许我删除整个网格部分,将此代码合并到小部件代码中,正如我所讨论的,大大减少了代码的大小和混乱,但增加了复杂性。
6.我所做的最后更改是对您的函数代码。 您的
getFilename1
和getFilename2
代码中存在一些小错误。 第一个错误是您想要调用 tk_getOpenFile ,因为我猜您只是获取现有文件名并将其传递给 gretag 。 (链接到“tk_getOpenFile”API)如果您使用tk_getOpenFile
该对话框将确保该文件存在。getFilename1
中的第二个错误是对话框有一个Cancel
按钮,如果用户单击此取消按钮,对话框将返回一个空字符串。 在这种情况下,您必须取消选中 ttk::checkbutton 并取消设置 CONF(colorimetric) 变量。 或者更正确地说,您必须将CONF(colorimetric)
设置为按钮的-offvalue
。 您可以通过向当前按钮发送单击事件来同时执行这两项操作。在
您的
finish
函数中,我将函数重命名为submit
(抱歉),并重写它以使用新的CONF
变量。答案
当然,这大部分都是不必要的。 我想为您提供一些有趣的 Tcl/Tk 代码供您思考,同时解决您的问题。 不过,此时我们应该有足够的词汇来回答您的问题。
您的变量未打印出来的原因是初始化和作用域。 您应该始终在稍后需要引用的小部件上使用
-variable
或-textvariable
。 我通常在构建包含的小部件之前初始化引用的变量。 因此,如果您完成了文件顶部的操作,那么您就可以在
finish
函数中执行以下操作:Variable Basics
As others have pointed out, the confusing to $ or not to $ notation can be simplified by the following rule.
It can become a little more confusing when you start to think of everything in Tcl as a string (it's really not, but close enough), so you can store the name of one variable in another and restore its value by reference.
Here the notation
set $foo
is evaluated in step - first$foo
yields its valuehi
and then theset
expression (when run with no third argument) attempts to return the value held in the variablehi
. This fails. The notationset $bar
takes the same steps but this timeset
can operate on the value ofbar
, which isfoo
, and thus returns the value offoo
which ishi
. (link to "set" API)Initialization
One problem you have in this script is initialization. In Tcl variables don't exist until they're assigned a value. That's clearly why trying to
set $foo
above didn't work, because there was no variablehi
.At the top of your script you attempt to declare a variable with,
which doesn't work, because you are already operating in global scope. Global "has no effect unless executed in the context of a proc body." (link to "global" API) You actually have to use a
set
command to initialize the variable. This is why none of your attempts to printcolorimetric
inproc finish
worked.Scope
The other problem you have in this script is scope, particularly with mixing global and procedural/local scope. You're correct that, had you initialized
colorimetric
correctly then the code,would have worked. Another way to achieve this is with,
My Solution
I'd like to present my solution. I admit that I've moved a lot of code around, and I will go into a short explanation of what changes I implemented to make it more concise.
Discussion of Changes
1. The first changes I made were to use the
-text
options on thettk::checkbutton
andttk::radiobutton
. Granted, using an extra label for these allows you to place the text before the button, but doing so is non-standard and requires more code.becomes
2. Next I used the similarities between these two checkbuttons to abstract the creation into a foreach. (I do this all the time in my Tcl code for work.) This generates much easier code to read and allows you to add/remove/swap names and tags for the widgets. It results in slightly more but much more versitile code.
becomes
3. The next change was to merge your
getFilename1
andgetFilename2
into a singlegetFilename
procedure. We can pass arguments into this function to determine who is calling it. I use thelist
command to generate the call for this new function. (link to "list" API)I also started to combine your
grid
commands into the widget code itself. Heremygrid
keeps a list of what needs to be gridded per line in the GUI and then is evaluated at the end of each section to propagate the GUI on the fly. (link to "grid" API)The previous code gets its final revision and becomes,
Then the
grid
command can be evaluated and themygrid
variable cleared after every use!4. If you've been paying attention I also added a
-variable
option to yourttk::checkbutton
and at this point started storing the button state in a global variableCONF
. This is a big change.Tk loves to pollute your global namespace and it's good practice to fight back. I usually put all of my configuration state in a global array, and set that right up top of the code so that anyone can come in and change the default state of my code, without digging into it or doing search/replace calls or anything like that. Just good practice, so wherever you had a variable I moved it into
CONF
and movedCONF
up top.5. Next I propagated these changes throughout your code. Almost all of the widget creation was susceptible to these revisions. With respect to the widget creation this sometimes made independent code sections larger. But it also allowed me to remove your entire grid section, merging this code up into the widget code as I've discussed, greatly decreasing the size and clutter of your code at the added expense of complexity.
6. The final changes I made were to your function code. You have a couple of minor bugs in your
getFilename1
andgetFilename2
code. The first bug was that you want to calltk_getOpenFile
because I gather you are only grabbing an existing file name to pass it togretag
. (link to 'tk_getOpenFile' API) If you usetk_getOpenFile
the dialog will make sure the file exists.The second bug in
getFilename1
is that the dialog has aCancel
button, and if the user clicks this cancel button the dialog returns an empty string. In this case you have to un-check thettk::checkbutton
and you have to unset theCONF(colorimetric)
variable. Or more correctly you have to setCONF(colorimetric)
to the button's-offvalue
. You can do both of these at once by sending a click event to the current button.becomes
In your
finish
function I renamed the function tosubmit
(sorry) and rewrote it to make use of the newCONF
variable.The Answer
Of course most of this was unnecessary. I wanted to give you some interesting Tcl/Tk code to think about while at the same time solving your problem. At this point we should have the vocabulary to answer your question, though.
The reason your variables weren't printing out was because of initialization and scope. You should always use a
-variable
or-textvariable
on widgets that you need to reference later. I generally initialize my referenced variables before building their containing widgets. So at the top of your file if you had done,Then you would have been able to do, in the
finish
function,您尚未为比色检查按钮分配任何变量。
将 -variable colorimetric 添加到检查按钮,然后完成
您可以使用:
放置 $::colorimetric
另外,首先设置 ::colorimetric 以选择默认值。 那
比试图弄乱小部件的状态更容易。
我看到比色可以有的值是“”和“-c”所以
我假设您将在 exec 行中使用该值。
请注意 [exec Something yada $::colorimetric Something] 会
那时可能行不通。 您可能需要 {*}$::colorimetric
exec 行以使参数在为空时消失。
You have not assigned any variable to the colorimetric checkbutton.
Add -variable colorimetric to the checkbutton, and then in finish
you can use:
puts $::colorimetric
Also, set ::colorimetric first to select your default value. That
is easier than trying to mess with the state of the widget.
I see that the values colorimetric can have are "" and "-c" so
I assume you will use that value in the exec line.
Beware that [exec something yada $::colorimetric something] will
probably not work then. You'll probably need {*}$::colorimetric in the
exec line to make the argument disappear if it is empty.
这是一个小 tcl 片段 - 从 tclsh 运行或
在 Tcl 中引用:
""
(双引号): 评估替换 ($variable){}
{波浪括号):将整个字符串视为不进行替换的文字[]
(方括号):将字符串作为带替换的命令执行作为替代方案,您可以在对话框中弹出诊断信息:
Here's a little tcl snippet - run from tclsh or wish
Quoting in Tcl:
""
(double quotes): Evaluate substitutions ($variable){}
{Squiggly brackets): Treat the entire string as a literal with no substitution[]
(Square brackets): Execute the string as a command with substitutionAs an alternative you could pop up the diagnostic in a dialog box:
在“# Just here”注释中,尝试添加
put $::gretagNum
:: 表示全局变量,并将 -variable 选项添加到小部件
始终是全球性的。
At your "# Just here" comment, try adding
puts $::gretagNum
:: signifies a global variable, and the -variable option to widgets
are always global.