Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tcl 具有多个命令行参数的按钮_Tcl_Tk - Fatal编程技术网

Tcl 具有多个命令行参数的按钮

Tcl 具有多个命令行参数的按钮,tcl,tk,Tcl,Tk,tcl中的按钮是否可以链接到多个命令行参数? 我有一个在点击按钮时运行的代码,一个以秒为单位的进度条形码也与之链接,并且应该在按下该按钮的同时启动。 我使用{}将这两个进程作为一个命令放在按钮命令参数中,但它失败了,出现了错误 代码片段 button .b -image $p -command {progressbar 300 run_structural_comparision} proc progressbar {seconds} { ttk::progressbar .pg -o

tcl中的按钮是否可以链接到多个命令行参数? 我有一个在点击按钮时运行的代码,一个以秒为单位的进度条形码也与之链接,并且应该在按下该按钮的同时启动。 我使用{}将这两个进程作为一个命令放在按钮命令参数中,但它失败了,出现了错误

代码片段

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]
}
您可以在即时按钮处理程序命令字符串中放置多个调用,但它很快就会变得复杂。但简而言之,请使用分号分隔这两个命令

如果使用if
update idletasks
,则应将其视为“代码气味”。即:避免使用。在这种情况下,在progressbar函数中,设置该条,然后在调用后调用
以更新进度状态


我怀疑你的
rm-rf
可能做不到你想要的。它可能会锁定界面,因为在命令完成之前你什么也得不到。更好的方法是编写一个函数来遍历目录树并使用
file delete
删除文件,然后你可以在执行过程中引发进度事件,并通过中断来保持UI的活动状态再次使用
之后的
将处理过程升级为块。

最简单的方法是创建一个调用这两个函数的过程。如果需要:

proc on_button_press {seconds} {
    after idle [list progressbar $seconds]
    after idle [list run_structural_comparision]
}
您可以在即时按钮处理程序命令字符串中放置多个调用,但它很快就会变得复杂。但简而言之,请使用分号分隔这两个命令

如果使用if
update 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一样)但你实际上一次只做一件事

但是