Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Weekend project: Countdown app

67 views
Skip to first unread message

Alexandru

unread,
Sep 26, 2015, 10:41:43 AM9/26/15
to
Hi,

here is my new weekend project: a countdown App written in Tcl/Tk, based on things I could find in the Wiki (http://wiki.tcl.tk/14149 and http://wiki.tcl.tk/946).

If anyone is interested in testing an improving it, that would be very nice.

At the moment the App has a few bugs, that I couldn't solve:
1. If I press the "Reset" or "Stop" button, I cannot start the countdown again.
2. The validate command of the spinboxes should update the analog clock, but it doesn't.
3. At the end of the countdown, the analog clock doesn't stop at zero.
4. The sound package doesn't find the audio file, although the file path is correct.

Thanks!

Have fun!
Alexandru


# package require Sound

variable Hours 0
variable Minutes 0
variable Seconds 0
variable totaltime 0
variable stop 0
variable sense -1
variable mode 12

canvas .c -width 200 -height 200
ttk::label .lh -text Hours
ttk::label .lm -text Minutes
ttk::label .ls -text Seconds
ttk::spinbox .eh -from 0 -to $mode -increment 1 -textvariable Hours -validate all -validatecommand {drawhands .c; return 1}
ttk::spinbox .em -from 0 -to 60 -increment 1 -textvariable Minutes -validate all -validatecommand {drawhands .c; return 1}
ttk::spinbox .es -from 0 -to 60 -increment 1 -textvariable Seconds -validate all -validatecommand {drawhands .c; return 1}
ttk::progressbar .pb -orient horizontal -mode determinate -variable totaltime
ttk::button .b1 -text Start -command Start
ttk::button .b2 -text Stop -command Stop
ttk::button .b3 -text Reset -command Reset

grid .c -sticky ewns -columnspan 3
grid .lh .lm .ls -sticky ew
grid .eh .em .es -sticky ew
grid .pb -columnspan 3 -sticky ew
grid .b1 .b2 .b3 -sticky ew

grid columnconfigure . 0 -weight 1
grid columnconfigure . 1 -weight 1
grid columnconfigure . 2 -weight 1

bind .c <Configure> [list drawdigits %W %w %h]

proc Start {} {
variable totaltime
variable Hours
variable Minutes
variable Seconds

set totaltime [expr $Seconds + $Minutes*60 + $Hours*360]
.pb configure -maximum $totaltime

coroutine totaltime countdown
}

proc Stop {} {
variable stop 1
}

proc Reset {} {
variable stop 1
variable totaltime 0
variable Hours 0
variable Minutes 0
variable Seconds 0
drawhands .c
}

proc countdown {} {
variable totaltime
variable Hours
variable Minutes
variable Seconds
variable stop
for { set totaltime $totaltime } { $totaltime >= 0 } { incr totaltime -1 } {
if {$totaltime > 0} {
after 1000 [info coroutine]
} else {
# sound C:/Windows/Media/Windows-Ping.wav
}
yield
if {$Seconds>0} {
incr Seconds -1
} else {
set Seconds 59
if {$Minutes>0} {
incr Minutes -1
} else {
set Minutes 59
if {$Hours>0} {
incr Hours -1
}
}
}
drawhands .c
update
if {$stop} {
# rename totaltime {}
break
}
}
}
proc drawhands {w {width 0} {height 0}} {
variable totaltime
variable sense
variable mode
$w delete hands
if {$width==0} {
set width [winfo width .c]
}
if {$height==0} {
set height [winfo height .c]
}
set xm [expr {$width/2.0}]
set ym [expr {$height/2.0}]
foreach divisor [list 60 3600 [expr {86400*$::mode/24.0}]] length {0.8 0.7 0.6} linewidth {1 2 3} {
set angle [expr {$totaltime*$::sense*2*acos(-1) / $divisor}]
set x [expr {$xm + $length * $xm * sin($angle)}]
set y [expr {$ym - $length * $ym * cos($angle)}]
$w create line $xm $ym $x $y -width $linewidth -tags hands
}
}
proc drawdigits {w width height} {
variable sense
variable mode
$w delete all
set xm [expr {$width/2.0}]
set ym [expr {$height/2.0}]
set radius 0.85
for {set i 1} {$i<=$::mode} {incr i} {
set a [expr {2*$i/double(${::mode})*$::sense*acos(-1)}]
set x [expr {$xm * (1 + $radius*sin($a))}]
set y [expr {$ym * (1 - $radius*cos($a))}]
set c [expr {$i%2 ? "black" : "black"}] ;# alternate colors
$w create text $x $y -text $i -tag t -fill $c
}
drawhands .c $width $height
}

Christian Gollwitzer

unread,
Sep 27, 2015, 3:04:50 AM9/27/15
to
Am 26.09.15 um 16:41 schrieb Alexandru:
> Hi,
>
> here is my new weekend project: a countdown App written in Tcl/Tk, based on things I could find in the Wiki (http://wiki.tcl.tk/14149 and http://wiki.tcl.tk/946).
>
> If anyone is interested in testing an improving it, that would be very nice.

Are you sure that you want to count down hours?
A similar one I made once for a gameshow is here:

http://wiki.tcl.tk/38113

It counts up instead of down (it is a stopwatch), but that could easily
be changed. It includes a clock megawidget with configurable tiling. It
also resizes with a constant aspect ratio. If you want to try, place a
couple of MP3s in the subdir music/ within the same directory as the
script. Or try the starpack from here:

http://www.auriocus.de/Software/Stoppuhr.exe

(beware: contains copyrighted music, so tell me that I can take it down
when you got it)

> At the moment the App has a few bugs, that I couldn't solve:
> 1. If I press the "Reset" or "Stop" button, I cannot start the countdown again.
> 2. The validate command of the spinboxes should update the analog clock, but it doesn't.

Obviously hitting the spinbuttons does not trigger the validator. I see
it executed when I change focus. Still drawhands does not make use of
the Hours, Minutes etc. variables.

> 3. At the end of the countdown, the analog clock doesn't stop at zero.
> 4. The sound package doesn't find the audio file, although the file path is correct.

Hmm.. My stopwatch also uses snack. It was able to play the music from
within a Starpack. I've never tried the package sound, though.
> for { set totaltime $totaltime } { $totaltime >= 0 } { incr
totaltime -1 } {
> if {$totaltime > 0} {
> after 1000 [info coroutine]

This is not reliable. After many iterations, the clock will lag, because
after only schedules the callback but makes no guarantee that you will
be called at exactly that time point. Usually it makes the delay longer.
Better measure [clock seconds] when the callback fires, and compute the
time which has passed since the start.

Christian

Donal K. Fellows

unread,
Sep 27, 2015, 3:23:26 AM9/27/15
to
On 27/09/2015 08:04, Christian Gollwitzer wrote:
> Better measure [clock seconds] when the callback fires, and compute the
> time which has passed since the start.

If you're doing timing properly, you will want to use several callbacks
a second (maybe 4 or 5?) and to use [clock milliseconds] as the time
standard. That will keep the degree of timing inaccuracy below what
people will notice.

Donal.
--
Donal Fellows — Tcl user, Tcl maintainer, TIP editor.
0 new messages