2017-07-25 6 views
0

Ich bin mit Tcl bequem, aber Neuling mit TK. Ich möchte einige Texte in einem Fenster anzeigen und nach mehreren Suchen habe ich hier ein Beispiel gefunden, das mir gut erscheint. Mein Problem ist, dass die Anzeige nicht in Echtzeit, sondern nur wenn das Programm endet. Hier sind die Hauptlinien meines Programms.Terminal Text nicht in tcltk Fenster Echtzeit angezeigt

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 
} 

Frage: was falsch ist oder in diesem Code verpasst? Kennen Sie ein Paket oder ein Beispiel, das ich verwenden kann, um Sätze in einem separaten Fenster anzuzeigen?

Hinweis: Ich benutze tcl tk 8.6.6 auf macOS Sierra 10.12.5

Antwort

2

Ihr Testprogramm wird in einer ereignisgesteuerten Art und Weise geschrieben, so dass die Probleme mit dem Bildschirm aktualisieren verschärft.

Die after 10 Anweisung wird das Programm hängen und nicht zulassen, dass die Ereignisschleife erneut eingegeben wird. Für die Zwecke der Prüfung nur versuchen:

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

anstelle des after 10 Befehl. Die Verwendung des Befehls vwait wird normalerweise nicht empfohlen, da verschachtelte vwait's nicht wie erwartet funktioniert.

Wenn Sie eine sehr ausgelastete Schleife haben, hat das Tk-Programm möglicherweise nie die Möglichkeit, seine Ereignisschleife erneut aufzurufen, und die Anzeige wird nie aktualisiert.

Die einfachste Lösung ist am Ende des writeToLog Verfahrens eine

update 

Anweisung zu setzen. Dies ist nicht immer der beste Weg, um diese Art von Problem zu behandeln, aber es funktioniert.

Es wird auch Ihre Schleife verlangsamen, da das Fenster jedes Mal neu gezeichnet werden muss, wenn eine Protokollnachricht geschrieben wird.

Eine andere Methode wäre, den Berechnungsprozess in einen separaten Thread oder Prozess zu verschieben und die Statusaktualisierungen an den GUI-Hauptprozess zu senden.

+0

Dank Brad, Ihre vwait Idee funktioniert perfekt. Ich werde Ihre zweite Idee mit einem separaten Thread versuchen. Es ist eine Idee, die ich sehr mag. –

Verwandte Themen