【问题标题】:Preventing instantaneous execution of this code?防止立即执行此代码?
【发布时间】:2015-01-08 14:41:17
【问题描述】:

我无法理解如何更新 Tk 中的小部件以反映正在进行的过程。 基本上,现在我的程序是递归扫描一个目录,并且应该将它找到的每个目录/文件一次输出到一个文本小部件。我的问题是,脚本不是这样做,而是找到所有目录,然后在完成后立即输出所有内容。代码如下:

proc scan {{dir .}} {
global num_items_found vs_list ec_list

foreach i [lsort [glob -nocomplain -dir $dir *]] {
    if {[file type $i]=="directory"} {
        .main.body.log insert end "Checking $i\n";
        scan $i;
    } else {
        if {[string tolower [file tail $i]] eq "buildlog.htm"} {
            lappend vs_list $i;
            incr num_items_found;
            .main.body.log insert end "Found $i\n";
        } elseif {[file extension $i] eq ".log"} {
            lappend ec_list $i;
            incr num_items_found;
            .main.body.log insert end "Found $i\n";
        }
    } 
}

return;
} 

我也在一个不同的过程中调用这个过程,在这个过程中我也在扫描之前禁用一个按钮并在之后重新启用它;但这也不起作用。在扫描过程执行之前,脚本根本不允许我的小部件更新?我怎样才能得到想要的结果?

谢谢!

【问题讨论】:

  • 你不要让事件循环运行并完成它的工作。看看wiki.tcl.tk/946
  • 谢谢!这对阅读很有帮助。

标签: recursion widget tcl tk


【解决方案1】:

Tk 中的大多数显示更新发生在事件循环中。在您的情况下,直到您完成目录遍历后才进入事件循环。您可能想要使用update idletasks 命令。

来自手册:

update idletasks 命令在对应用程序状态进行了更改并且您希望这些更改立即显示在显示屏上而不是等待脚本完成的脚本中很有用。大多数显示更新都是作为空闲回调执行的,因此update idletasks 将导致它们运行。但是,有些更新仅在响应事件时发生,例如由窗口大小更改触发的更新;这些更新不会发生在更新空闲任务中。

【讨论】:

  • 如果您采取措施避免重入问题,update 会更好,因为它允许您处理来自操作系统的重绘请求。 OTOH,您必须小心处理它,否则您最终会对事件处理程序进行不必要的递归调用;这是often considered harmful 有充分的理由。
  • 感谢您的反馈;很有帮助。
猜你喜欢
  • 2021-02-16
  • 1970-01-01
  • 2016-11-26
  • 1970-01-01
  • 1970-01-01
  • 2019-11-29
  • 2016-07-07
  • 2018-06-04
  • 1970-01-01
相关资源
最近更新 更多