I do have a TK/TCL stopwatch starting a unix counter from an xterm, but it doesn't display the count in the counter image. After the unix counter finished (it has 4 iterations), then the display in the stopwatch is shown and counting. How to keep showing the count after clicking on the run button ?
stopwatch with its buttons control
Here's the code (replace your appropriate 'wish' in line 3):
#!/bin/sh
####################################################################### \
exec /sw/freetools/tk/8.5.6/Linux/rh5/x86_64/bin/wish8.5 "$0" ${1+"$@"}
package require Tk
wm title . "TEST-GUI"
. configure -padx 50 -pady 50 -relief raised -borderwidth 2
###STOPWATCH -begin-
set COLOR_BACKGROUND "black"
set COLOR_FOREGROUND "sky blue"
font create FONT0 -family {VL PGothic} -size -20 -weight normal
set ::time 00:00:00
proc every {ms body} {
eval $body
after $ms [namespace code [info level 0]]
}
proc Start {} {
if {$::time eq {00:00:00}} {
set ::time0 [clock clicks -milliseconds]
}
every 10 {
set m [expr {[clock clicks -milliseconds] - $::time0}]
set ::time [format %2.2d:%2.2d:%2.2d [expr {$m/60000}] [expr {($m/1000)%60}] [expr {$m%1000/10}]]
}
.frame1.run config -state disabled
}
proc Stop {} {
if {[llength [after info]]} {
after cancel [after info]
} else {set ::time 00:00:00}
.frame1.run config -state normal
}
###STOPWATCH -end-
frame .frame1 -highlightbackground black \
-highlightthickness 1 \
-width 200 -height 200
label .frame1.time -textvar ::time -font FONT0 -background $COLOR_BACKGROUND -foreground $COLOR_FOREGROUND
button .frame1.run -text "RUN" -foreground black -bg coral \
-borderwidth 3 -height 0 -width 3 -font {-family symbol -size 8} -pady 2 \
-command {
Start
gui_run
}
button .frame1.exit -text "EXIT" -foreground black \
-borderwidth 3 -height 0 -width 3 -font {-family symbol -size 8} -pady 2 \
-command {exit}
pack .frame1
pack .frame1.run -side top
pack .frame1.exit -side bottom
pack .frame1.time
proc xterm_counter {} {
set fileid [open "./xterm_counter.txt" w]
puts $fileid "#!/bin/csh -f"
puts $fileid ""
puts $fileid "set i = 0"
puts $fileid "echo \"testing programm counting -start- \`date +%X\`\""
puts $fileid "while (\$i <= 3)"
puts $fileid " sleep 2"
puts $fileid " set i = \`expr \$i + 1\`"
puts $fileid " echo \"testing programm counting here => \$i\""
puts $fileid "end"
puts $fileid "echo \"testing programm counting -end- \`date +%X\`\""
close $fileid
}
proc gui_run {} {
xterm_counter
exec chmod 744 "./xterm_counter.txt"
if {[catch {exec ./xterm_counter.txt >@ stdout}]} {
puts "RUN FAILED, exit programm"
exit
} else {
puts "RUN SUCCESSFULL, stop stopwatch now"
}
}
I'm not able to stop the stopwatch after the counter has finished. I added the "Stop" command in the button .frame1.run to execute it, not working:
button .frame1.run -text "RUN" -foreground black -bg coral \
-borderwidth 3 -height 0 -width 3 -font {-family symbol -size 8} -pady 2 \
-command {
Start
gui_run
puts "after.."
after 1000
puts "Stop.."
Stop
}
The other points is how to run simultaneously the counter and the stopwatch together, and when the counter has finished the stopwatch schould stop ..?
The problem is that the exec
command pauses the Tcl process until the other process completes running. This isn't a big problem for something quick like the running of chmod
, but for a long running timer display it is a major pain.
The simplest fix, especially if you don't really care about whether the subprocess works very much, is to put a &
word at the end of the exec
so the code is run in the background, disconnected from Tcl.
exec ./xterm_counter.txt >@stdout &
(That returns the process ID if I remember right, letting you pull periodically for termination.)
If that doesn't work for you, your options are to either run the code in a pipeline (with that redirection, it would be a write-only pipe) or to run it from a worker thread.