Version 18 of clock.tcl

Updated 2005-07-25 15:07:18

# clock.tcl

 proc every {ms body} {
    eval $body
    after $ms [list every $ms $body]
 }
 pack [label .l -textvar time -font {Tahoma 24}]
 pack [button .b -text X -command exit]
 every 1000 {set ::time [clock format [clock sec] -format %H:%M:%S]}

LV It probably would be best for whomever added the above to add a name and a EULA type statement indicating the code is allowed to be reused. - RS: I put it here in order to test whether pages with .tcl titles are still delivered as plain text (they aren't), and trying to have my XDA execute it somehow - but it didn't work :( And re licensing: doesn't Who owns the content of this Wiki tell it clearly enough?

Well, it certainly sets a general expectation. However, applications having the licensing spelled out explicitly ensures there is no confusion when the application is reaped from the wiki into a distribution.


EKB Here's a version that has a task timer as well as a clock. It lacks the elegant simplicity of the code above, but it adds some functionality that I was looking for. It's also set to be always on top, at least on Windows.

I've updated this with a new and improved version (July 25, 2005). I've actually ended up using it a lot for keeping track of my billed time. Here's what it looks like:

http://www.kb-creative.net/screenshots/Timer.gif

 wm attributes . -topmost 1
 wm resizable . 0 0

 image create photo resetclock16 -data {
   R0lGODlhEAAQAIUAAAT+BHy+/HS6/Gy2/ITC/Pz+/Fyu/FSm/Pz6/PT6/Eye
   9PzmhPzqnPzurOTy/OTu/ESW7PzmjPzqpAR2/PzyxPz2xPz2zNTm/ARy/Pzy
   zPz23Mzi/Lza/DyK3PzutPzyvPz67Pz63DyO5LTW/DSC3Pz21JzK/DSC1CR6
   zPz+9IS+/FSq/PwWFPxmZIy+/LRypPwCBPT2/PyWlKwuVLRunOz2/HxKfMTe
   /IS6/Kx6rKzS/JTG/JyS1PQKFNQaLDSG1CH5BAEAAAAALAAAAAAQABAAAAa7
   QIBQGAgIBIPBcAkgBArQqOHAJESRA0MBkVAMrYXjgsFoHA6OB4QYXkQYkgml
   YlFc1s/wu4yhZDQQGxwdTwJvEh4fExYgISAiIyQCBQNkDR4TGCUaICAdJieT
   A4gYmROdIAWfKAMFBpcUJZudKQUnKqxQKxV/jiAsLScuLzAABjEHGSWoKTIw
   MzQwxSs1DwoQnVAkNtIzQwoPGzciJ+U4OdLFQxAQOjomOyo8PT7STAAdPyQo
   KPYA0n6CAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIu
   NQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQu
   DQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7
 }

 image create photo appclock16 -data {
   R0lGODlhEAAQAIUAAPwCBHy+/HS6/Gy2/ITC/Pz+/Fyu/FSm/Pz6/ESW7Pzm
   hPzqnPzurOz2/OTu/PzmjPzqpAR2/PzyxPz2xPz2zEye9NTm/ARy/Pz21Mzi
   /Lza/DyK3PzutPzyvPzyzPz63Pz67DyO5KzS/Pz23KTO/DSC1DSC3JzK/CR6
   zPz+9Iy+/FSq/IS6/BxyxPT2/Hy2/HSy/MTe/Gyu/CRyxJTG/IS+/DSG1AAA
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaz
   QIBQGAgIBIPBcAkgBArQqOHAJESRA0MBgUgMrYWjYrFgHA4NhxfwFCgeC0hE
   MqFULN5nGF6+SDAYCRkaG21wEBwdER4fICAhIhsCBQNkDBwRFxgjjhskJZMD
   iBeZF44gBSYnKAMFBpd/m44pKSUqrFArE4yNqKkqLC0ABi4HHhinBSkFLS/C
   ACtpFQmOUCYlLDDPABUOGTEhJeIvLzIzTAkJIiInNDXO20wbNiYoKOdLfkEA
   If5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2
   ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDov
   L3d3dy5kZXZlbGNvci5jb20AOw==
 }

 proc every {ms body} {
    eval $body
    after $ms [list every $ms $body]
 }

 proc timeElapsed {sec} {
    set hours [expr {$sec / 3600}]
    set mins [expr {($sec / 60) % 60}]
    return [format "%02d:%02d" $hours $mins]
 }

 # Are we timing, or not?
 set timerstate 0
 # Has the timer been reset?
 set reset 1
 # Store previous time elapsed
 set prevtime 0
 proc toggleTimer {b} {
    if {$::timerstate} {
        $b config -relief flat
        set ::timerstate 0
        set ::prevtime [expr {$::prevtime + [clock sec] - $::t0}]
    } else {
        $b config -relief sunken
        if {$::reset} {
            set ::reset 0
        }
        set ::t0 [clock sec]
        set ::timerstate 1
    }
 }
 proc resetTimer {b} {
    set ::reset 1
    set ::telapsed "00:00"
    set ::t0 [clock sec]
    set ::prevtime 0
 }

 ## -- Top frame
 pack [frame .top] -side top
 pack [label .top.l -textvar time -font {Tahoma 18}] -side left

 # Buttons
 pack [frame .top.buttons] -side right
 set clockbutton [button .top.buttons.t -image appclock16 -relief flat]
 pack $clockbutton -side left
 set resetbutton [button .top.buttons.close -image resetclock16 -relief flat]
 pack $resetbutton -side left

 ## -- Bottom frame
 pack [frame .bottom] -side bottom
 pack [label .bottom.l -textvar telapsed -font {Tahoma 10}]

 $clockbutton config -command "toggleTimer $clockbutton"
 $resetbutton config -command "resetTimer $clockbutton"

 ## -- Start!
 set telapsed "00:00"
 every 1000 {
    set ::time [clock format [clock sec] -format %H:%M]
    if {$::timerstate} {set ::telapsed [timeElapsed [expr {$::prevtime + [clock sec] - $::t0}]]}
 }

escargo 19 Jul 2005 - Here is a variation that I created so that the time would show even if the application was reduced to the Windows Taskbar. However, there is some behavior that I found quite curious. So, here is a slight change from the original code, primarily to set the time into the applications title and the iconname.

 proc every {ms body} {
    eval $body
    after $ms [list every $ms $body]
 }

 proc update {} {
     set ::time [clock format [clock sec] -format %H:%M:%S]
     wm title . $::time
     wm iconname . $::time
 }


 pack [label .l -textvar time -font {Tahoma 24}]
 pack [button .b -text Exit -command exit]
 every 1000 {update}

Now, here is the curious behavior. If this app is run (on Windows XP Pro with ActiveTcl 8.4.9), if the app is minimized so that it's on the task bar, the timer updates. (It's only advantage over the taskbar clock is that it counts the seconds.) But if there are two Tcl apps running at the same time, the taskbar shows "2 Wish Application" (because of stacking of the two apps because the taskbar is full). If you click on the taskbar icon for the two apps the iconnames show but the iconnames don't update! Even more amusing is that the iconnames appear in tooltips when you roll over the iconnames with the updated values that are not shown in the iconnames. It's not clear what the expected behavior ought to be; I thought that the iconnames should update just as well when the iconnames are stacked as when they are sitting on the taskbar, but apparently some graphical update threads are not being called when they are stacked.


Category Application | Category GUI | Category Date and Time