ActiveState Code

Recipe 124894: Stopwatch in Tkinter


This is a small implementation of a stopwatch widget in Tkinter. The widget displays a label with minutes:seconds:1/100-seconds. The label is updated every 50 ms, but that can easily be changed. Methods are availble for starting, stopping and resetting the stopwatch. A simple program demonstrates the widget.

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
from Tkinter import *
import time

class StopWatch(Frame):  
    """ Implements a stop watch frame widget. """                                                                
    def __init__(self, parent=None, **kw):        
        Frame.__init__(self, parent, kw)
        self._start = 0.0        
        self._elapsedtime = 0.0
        self._running = 0
        self.timestr = StringVar()               
        self.makeWidgets()      

    def makeWidgets(self):                         
        """ Make the time label. """
        l = Label(self, textvariable=self.timestr)
        self._setTime(self._elapsedtime)
        l.pack(fill=X, expand=NO, pady=2, padx=2)                      
    
    def _update(self): 
        """ Update the label with elapsed time. """
        self._elapsedtime = time.time() - self._start
        self._setTime(self._elapsedtime)
        self._timer = self.after(50, self._update)
    
    def _setTime(self, elap):
        """ Set the time string to Minutes:Seconds:Hundreths """
        minutes = int(elap/60)
        seconds = int(elap - minutes*60.0)
        hseconds = int((elap - minutes*60.0 - seconds)*100)                
        self.timestr.set('%02d:%02d:%02d' % (minutes, seconds, hseconds))
        
    def Start(self):                                                     
        """ Start the stopwatch, ignore if running. """
        if not self._running:            
            self._start = time.time() - self._elapsedtime
            self._update()
            self._running = 1        
    
    def Stop(self):                                    
        """ Stop the stopwatch, ignore if stopped. """
        if self._running:
            self.after_cancel(self._timer)            
            self._elapsedtime = time.time() - self._start    
            self._setTime(self._elapsedtime)
            self._running = 0
    
    def Reset(self):                                  
        """ Reset the stopwatch. """
        self._start = time.time()         
        self._elapsedtime = 0.0    
        self._setTime(self._elapsedtime)
        
        
def main():
    root = Tk()
    sw = StopWatch(root)
    sw.pack(side=TOP)
    
    Button(root, text='Start', command=sw.Start).pack(side=LEFT)
    Button(root, text='Stop', command=sw.Stop).pack(side=LEFT)
    Button(root, text='Reset', command=sw.Reset).pack(side=LEFT)
    Button(root, text='Quit', command=root.quit).pack(side=LEFT)
    
    root.mainloop()

if __name__ == '__main__':
    main()

Discussion

According to the comments about time.clock(), I have changed them to time.time().

Comments

  1. 1. At 2:51 a.m. on 6 may 2002, Tobias Klausmann said:

    Nearly right, but... ...using time.time() instead of time.clock() will measure real time instead of the time the program has got. Will work with Python2 only.

  2. 2. At 11:37 a.m. on 7 may 2002, Jørgen Cederberg (the author) said:

    time.clock(). My motive for using time.clock() was, that it says in the documentation that time.clock() is used for timing or benchmarking algorithms (even in Python 1.5.2, which I have never used). Further, as time is only measured relatively, it does not matter what the time is, when starting and stopping the stopwatch.

  3. 3. At 11:46 p.m. on 21 may 2002, Tobias Klausmann said:

    time.clock(). Well, time.clock() returns the CPU time the process has received so far, so if it doesn't get 100% CPU time, the programs perception of time will be slower than the real time.

    It is used for benchmarking so that other programs running on the machine don't influence the benchmark outcome.

Sign in to comment