Tcl 具有多个命令行参数的按钮
tcl中的按钮是否可以链接到多个命令行参数? 我有一个在点击按钮时运行的代码,一个以秒为单位的进度条形码也与之链接,并且应该在按下该按钮的同时启动。 我使用{}将这两个进程作为一个命令放在按钮命令参数中,但它失败了,出现了错误 代码片段Tcl 具有多个命令行参数的按钮,tcl,tk,Tcl,Tk,tcl中的按钮是否可以链接到多个命令行参数? 我有一个在点击按钮时运行的代码,一个以秒为单位的进度条形码也与之链接,并且应该在按下该按钮的同时启动。 我使用{}将这两个进程作为一个命令放在按钮命令参数中,但它失败了,出现了错误 代码片段 button .b -image $p -command {progressbar 300 run_structural_comparision} proc progressbar {seconds} { ttk::progressbar .pg -o
button .b -image $p -command {progressbar 300 run_structural_comparision}
proc progressbar {seconds} {
ttk::progressbar .pg -orient horizontal -mode determinate -maximum $seconds
pack .pg -side left
update idletasks
# Do some real work here for $seconds seconds
for {set i 0} {$i < $seconds} {incr i} {
after 1000; # Just waiting in this example, might as well do something useful here
.pg step; # After some part of the work, advance the progressbar
update idletasks; # Needed to update the progressbar
}
# Done, clean up the dialog and progressbar
}
proc run_structural_comparision {} {
type_run
global ENTRYfilename ENTRYfilename2 curDIR curDIR2 typep reflib compLib rundir hvt_verilog logfile
set path [concat $reflib $compLib]
## set path [concat $ENTRYfilename $ENTRYfilename2]
puts $path
set str "compare_structure -overlap_when -type {timing constraint} -report compare_structure_"
set trt ".txt"
set structure [concat [string trim $str][string trim $typep][string trim $trt] $path]
puts $structure
puts $rundir
cd $rundir
set filename [concat "compare_structure_" $typep ".tcl"]
if {[ file exists $rundir/$filename] == 1 } {
exec rm -rf $rundir/compare_structure_$typep.tcl
}
button.b-image$p-command{progressbar 300运行\u结构\u比较}
进程条{秒}{
ttk::progressbar.pg-定向水平-模式确定-最大$秒
包装。pg-左侧
更新idletasks
#在这里做一些真正的工作,花费$seconds
对于{set i 0}{$i<$seconds}{incr i}{
1000之后;#在本例中只是等待,不如在这里做一些有用的事情
.pg步骤#完成部分工作后,推进进度条
更新idletasks;#需要更新progressbar
}
#完成后,清理对话框和进度栏
}
过程运行结构比较{{
运行类型
全局入口文件名入口文件名2 curDIR curDIR2 typep reflib compLib rundir hvt_verilog日志文件
设置路径[concat$reflib$compLib]
##设置路径[concat$ENTRYfilename$ENTRYfilename2]
放置$path
设置str“compare_structure-overlap_when-type{timing constraint}-report compare_structure”
设置trt“.txt”
集合结构[concat[string trim$str][string trim$typep][string trim$trt]$path]
看跌美元结构
放入$rundir
cd$rundir
设置文件名[concat“compare_structure”$typep.tcl]
如果{[file exists$rundir/$filename]==1}{
exec rm-rf$rundir/compare_structure_u$typep.tcl
}
最简单的方法是创建一个调用这两个函数的过程。如果需要:
proc on_button_press {seconds} {
after idle [list progressbar $seconds]
after idle [list run_structural_comparision]
}
您可以在即时按钮处理程序命令字符串中放置多个调用,但它很快就会变得复杂。但简而言之,请使用分号分隔这两个命令
如果使用ifupdate idletasks
,则应将其视为“代码气味”。即:避免使用。在这种情况下,在progressbar函数中,设置该条,然后在调用后调用以更新进度状态
我怀疑你的rm-rf
可能做不到你想要的。它可能会锁定界面,因为在命令完成之前你什么也得不到。更好的方法是编写一个函数来遍历目录树并使用file delete
删除文件,然后你可以在执行过程中引发进度事件,并通过中断来保持UI的活动状态再次使用之后的将处理过程升级为块。最简单的方法是创建一个调用这两个函数的过程。如果需要:
proc on_button_press {seconds} {
after idle [list progressbar $seconds]
after idle [list run_structural_comparision]
}
您可以在即时按钮处理程序命令字符串中放置多个调用,但它很快就会变得复杂。但简而言之,请使用分号分隔这两个命令
如果使用ifupdate idletasks
,则应将其视为“代码气味”。即:避免使用。在这种情况下,在progressbar函数中,设置该条,然后在调用后调用以更新进度状态
我怀疑你的rm-rf
可能做不到你想要的。它可能会锁定界面,因为在命令完成之前你什么也得不到。更好的方法是编写一个函数来遍历目录树并使用file delete
删除文件,然后你可以在执行过程中引发进度事件,并通过中断来保持UI的活动状态再次在
之后使用将处理升级为块。按钮的-命令
回调是一个Tcl脚本。它将在堆栈的全局级别上进行计算。如果要运行两个命令,可以在其中放入一个脚本来运行这两个命令:
button .b -command { command_1; command_2 }
这将按顺序运行它们。Tcl自然是单线程的,因为这是迄今为止人们最容易使用的编程模型。通过执行回调可以使代码看起来同时执行多项操作(Tk就是这样工作的,就像地球上几乎所有其他GUI一样)但你实际上一次只做一件事
但你真正的问题是…
您需要的核心是一种在后台运行程序的方法,这种方法需要很长时间,以便您可以监视它并继续更新GUI。不幸的是,这不是一个简单的主题,正确的答案将取决于到底发生了什么
最简单的技术之一是在子流程中执行CPU绑定的处理。在这种情况下,您可以通过管道运行子流程,并设置fileevent
,以便在生成输出或程序终止时向您发出通知回调。Tcl非常擅长这类事情;许多语言都有类似的功能当使用Tcl时,先进的技术会让人感觉很自然,因为在如何使I/O回调很好地工作方面已经投入了大量的精力
如果它在进程中长期运行,没有回调的机会,那么事情会变得更复杂,因为你必须在不同的线程中进行处理和GUI更新。如果一切都设置正确,这并不难,但可能需要对你的程序进行实质性的重新架构(Tcl中的线程通常会彼此进行非常强的分区)。按钮的-command
回调是一个Tcl脚本。它将在堆栈的全局级别上进行计算。如果要运行两个命令,可以在其中放一个脚本来运行这两个命令:
button .b -command { command_1; command_2 }
这将按顺序运行它们。Tcl自然是单线程的,因为这是迄今为止人们最容易使用的编程模型。通过执行回调可以使代码看起来同时执行多项操作(Tk就是这样工作的,就像地球上几乎所有其他GUI一样)但你实际上一次只做一件事
但是