2017-07-25 97 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主意完美工作。 我會嘗試你的第二個想法與單獨的線程。這是一個我喜歡很多的想法。 –