2017-07-25 35 views
0

我很喜欢tcl,但新手使用tk。 我想在窗口上显示一些文本,经过几次搜索后,我在这里找到了一个对我来说很好的示例。 我的问题是,显示不是实时投入,但只有当程序结束。 这是我的程序的主线。终端文本不显示在tcltk窗口实时

Main_program.tcl

#!/bin/sh 
# -*- tcl -*- 
# The next line is executed by /bin/sh, but not tcl \ 
exec /usr/local/Cellar/tcl-tk/bin/tclsh "$0" "[email protected]" 

set DEBUG 1 

source ./GUI_mgt.tcl 
source ./utils.tcl 

for {set i 0} {$i<500} {incr i} { 
    after 10 
    debug_puts $i 
} 

utils.tcl

proc debug_puts {message} { 
    if {$::DEBUG} { writeToLog $message } 
} 

GUI_mgt.tcl

package require Tk 
grid [text .log -state disabled -width 80 -height 24 -wrap none] 

proc writeToLog {msg} { 
    set numlines [lindex [split [.log index "end - 1 line"] "."] 0] 
    .log configure -state normal 
    if {$numlines==24} {.log delete 1.0 2.0} 
    if {[.log index "end-1c"]!="1.0"} {.log insert end "\n"} 
    .log insert end "$msg" 
    .log configure -state disabled 
} 

问:什么是错的或在此代码错过了什么? 你知道一些可以用来在单独窗口上显示句子的软件包或例子吗?

注:我用在MacOS塞拉利昂10.12.5

回答

2

你的测试程序没有写在一个事件驱动的方式TCL TK 8.6.6,因此与更新屏幕的问题加剧。

after 10声明将挂起程序并且不允许事件循环重新进入。仅用于测试目的,请尝试:

set ::w10 0 
after 10 [list set ::w10 1] 
vwait ::w10 

而不是after 10命令。通常不推荐使用vwait命令,因为嵌套的vwait's不能按预期工作。

当你有一个非常繁忙的循环时,Tk程序可能永远不会有机会重新进入它的事件循环,并且显示永远不会更新。

最简单的办法是把一个

update 

声明在writeToLog过程结束。这并不总是处理这类问题的最佳方法,但它很有效。

它也会减慢你的循环,因为每次写入日志消息时都必须重新绘制窗口。

另一种方法是将计算过程放到单独的线程或进程中,并将状态更新发送到主GUI进程。

+0

感谢Brad,你的vwait主意完美工作。 我会尝试你的第二个想法与单独的线程。这是一个我喜欢很多的想法。 –

相关问题