问题描述
假设有一个包含无限循环条件的 a.tcl,例如,
while {1} {
puts $val
}
我想实现一个 tk-button,它执行 a.tcl 文件并继续运行并以固定的时间间隔在 tk-text 窗口中打印 $val,例如每 1 秒。 另外,当我们再次点击那个按钮时,它应该停止运行 a.tcl
注意:我尝试使用 exec tclsh a.tcl
但由于 a.tcl 中的无限 while 循环,它挂起了 tk 窗口
解决方法
如果不是使用 exec
,而是使用以下命令启动子进程:
set pipeline [open |[list tclsh a.tcl]]
然后 GUI 将保持活动状态。但是,您可能希望不时从管道中读取数据。
proc line_per_second {pipeline} {
puts [gets $pipeline]
after 1000 line_per_second $pipeline
}
line_per_second $pipeline
当您 close $pipeline
时,它应该关闭(因为操作系统管道已关闭)。
请注意,对于真正的代码,而不是尽可能快地一遍又一遍地喷出同一行的代码,您可以改用可读的 fileevent
来触发对 gets
的调用。
proc read_line {pipeline} {
gets $pipeline line
if {[eof $pipeline]} {
close $pipeline
} else {
puts $line
}
}
fileevent $pipeline readable [list read_line $pipeline]
但是,使用您的特定脚本可能会过于频繁地触发并使事件的 GUI 有点饥饿。这只是非常大量输出的问题。