如何在 tcl / tk 中开发对话计,通过移动它获取循环值并在比例小部件中更新
How to develop dialog gauge in tcl / tk that gets loop value and updates in scale widget by moving it
我正在尝试制作一个进度条对话框,例如 GNU/Linux Xdialog --gauge
显然您应该得到一个值,该值会不时更新 'one second'。
这个增量是通过一个 for
循环完成的,该循环已经预先配置为提供累进计数。
根据我所做的测试,我对 tcl/tk 的了解程度是这样的:
proc bar { pos } {
global txt
set txt $pos
}
set btn [button .btn -text "Play" -relief groove -command { bar $pos }]
scale .scl -length 200 -width 5 -orient horizontal -from 0 -to 100 -resolution 1 -variable value -sliderlength 5 -sliderrelief flat -activebackground blue -command { bar } -showvalue 0
label .lbl -textvariable txt -width 5
grid $btn -row 0 -column 0
grid .scl -row 0 -column 1
grid .lbl -row 0 -column 2
global value
for {set value 0} {$value < 10} {incr value} {
after 1000; # delay
if {$value < 10} { puts "Number: $value" }
bind . "$btn invoke"
}
这行得通,所以在控制台中..它不显示表单,window 比例小部件正在缓慢移动。所以我需要最有经验的人的帮助,我怎样才能得到这个?
我创建了一个多帧动画以获得更好的创意。看:
问题是你有一个同步延迟循环。您需要一个异步的,以便可以处理显示更新。
coroutine countUp apply {{} { # <<< launch coroutine for asynchronous state
global value
for {set value 0} {$value < 10} {incr value} {
after 1000 [info coroutine]; yield; # <<< suspend coro for 1 second
puts "Number: $value"
}
}}
(没有协程也可以写出这段代码,但是代码不太清晰。)
并且建议您在需要进度条时使用ttk::progressbar
。更正用户视觉提示等。
命令
after 1000; # delay
只是阻止,不允许 Tcl/Tk 进行任何处理。
由于您的程序还没有进入事件循环,所以不会显示任何内容。
在某些情况下,最终替换 'after' 命令的任何代码都将具有
允许屏幕更新的延迟。
# don't put the bind inside the for loop
# is this even needed?
bind . "$btn invoke"
set ::waitvar 0
for {set value 0} {$value < 10} {incr value} {
# a simplistic solution for purposes of this example
# vwait cannot be nested, and should be used very carefully or not at all.
after 1000 set ::waitvar 1
vwait ::waitvar
set ::waitvar 0
}
更好的方法应该是:
proc updateScale { v } {
global value
set value $v
}
proc checkProgress { } {
# query the progress of the task and see how far along it is
set progress [queryProgress]
updateScale $progress
after 1000 [list checkProgress]
}
# schedule a call to checkProgress to start things off.
after 1000 [list checkProgress]
# and now the program enters the event loop
我正在尝试制作一个进度条对话框,例如 GNU/Linux Xdialog --gauge
显然您应该得到一个值,该值会不时更新 'one second'。
这个增量是通过一个 for
循环完成的,该循环已经预先配置为提供累进计数。
根据我所做的测试,我对 tcl/tk 的了解程度是这样的:
proc bar { pos } {
global txt
set txt $pos
}
set btn [button .btn -text "Play" -relief groove -command { bar $pos }]
scale .scl -length 200 -width 5 -orient horizontal -from 0 -to 100 -resolution 1 -variable value -sliderlength 5 -sliderrelief flat -activebackground blue -command { bar } -showvalue 0
label .lbl -textvariable txt -width 5
grid $btn -row 0 -column 0
grid .scl -row 0 -column 1
grid .lbl -row 0 -column 2
global value
for {set value 0} {$value < 10} {incr value} {
after 1000; # delay
if {$value < 10} { puts "Number: $value" }
bind . "$btn invoke"
}
这行得通,所以在控制台中..它不显示表单,window 比例小部件正在缓慢移动。所以我需要最有经验的人的帮助,我怎样才能得到这个?
我创建了一个多帧动画以获得更好的创意。看:
问题是你有一个同步延迟循环。您需要一个异步的,以便可以处理显示更新。
coroutine countUp apply {{} { # <<< launch coroutine for asynchronous state
global value
for {set value 0} {$value < 10} {incr value} {
after 1000 [info coroutine]; yield; # <<< suspend coro for 1 second
puts "Number: $value"
}
}}
(没有协程也可以写出这段代码,但是代码不太清晰。)
并且建议您在需要进度条时使用ttk::progressbar
。更正用户视觉提示等。
命令
after 1000; # delay
只是阻止,不允许 Tcl/Tk 进行任何处理。 由于您的程序还没有进入事件循环,所以不会显示任何内容。
在某些情况下,最终替换 'after' 命令的任何代码都将具有 允许屏幕更新的延迟。
# don't put the bind inside the for loop
# is this even needed?
bind . "$btn invoke"
set ::waitvar 0
for {set value 0} {$value < 10} {incr value} {
# a simplistic solution for purposes of this example
# vwait cannot be nested, and should be used very carefully or not at all.
after 1000 set ::waitvar 1
vwait ::waitvar
set ::waitvar 0
}
更好的方法应该是:
proc updateScale { v } {
global value
set value $v
}
proc checkProgress { } {
# query the progress of the task and see how far along it is
set progress [queryProgress]
updateScale $progress
after 1000 [list checkProgress]
}
# schedule a call to checkProgress to start things off.
after 1000 [list checkProgress]
# and now the program enters the event loop