Kivy - Stopwatch App



In this chapter, we shall build a Stopwatch app using Python's Kivy GUI framework. A stopwatch measures the time elapsed between the instances of starting an event and stopping it. For example, the stopwatch used to measure the time taken by an athlete to complete a 100-meter run.

The GUI design for the app should resemble the following figure −

Kivy Stopwatch App

The following "kv" script is used to place two labels and two buttons as shown in the above figure. The top label will be used to display the current time, and the label at the bottom will display the time elapsed after the timer is started. The left button is used to start/stop the stopwatch. The one on right resets the timer to 0.

BoxLayout:
   orientation: 'vertical'
   
   Label:
      id: time
      font_size:40
      markup:True
      text: '[b]00[/b]:00:00'
   
   BoxLayout:
      orientation: 'horizontal'
      padding: 20
      spacing: 20
      height: 90
      size_hint: (1, None)
      
      Button:
         text: 'Start'
         id: start_stop
         on_press : app.start_stop()
         
      Button:
         id: reset
         text: 'Reset'
         on_press: app.reset()
   Label:
      id: stopwatch
      font_size:40
      markup:True
      text:'00:00.[size=40]00[/size]'

In the application code, we define an on_stop() event handler that is invoke as soon as the GUI is populated. It schedules a time event handler which updates the label with current time after each second.

def on_start(self):
   Clock.schedule_interval(self.update_time, 0)

The update_time() method updates the current time displayed on the upper label (with id as time), and time elapsed on the lower label (with id as stopwatch) - if the timer has been started.

def update_time(self, t):
   if self.sw_started:
      self.sw_seconds += t
   minutes, seconds = divmod(self.sw_seconds, 60)
   part_seconds = seconds * 100 % 100
   self.root.ids.stopwatch.text = "{:2d} : {:2d}.{:2d}".format(int(minutes), int(seconds), int(part_seconds))
   self.root.ids.time.text = strftime('[b]%H[/b]:%M:%S')

The Button with id=start is bound to start_stop() method which stores the status of the stopwatch whether it has started or stopped and accordingly updates the caption of the start button (with id as start_stop).

def start_stop(self):
   self.root.ids.start_stop.text = 'Start' if
self.sw_started else 'Stop'
   self.sw_started = not self.sw_started

The button on right resets the time counter to 0, sets the caption of the other button to start and also resets the caption of the bottom label to 0:0.0.

def reset(self):
   if self.sw_started:
      self.root.ids.start_stop.text = 'Start'
      self.sw_started = False
   self.sw_seconds = 0

Example

The entire coding logic is gien in the code below −

from time import strftime
from kivy.clock import Clock
from kivy.app import App
from kivy.core.window import Window

Window.size = (720, 400)

class StopWatchApp(App):
   sw_seconds = 0
   sw_started = False

   def update_time(self, t):
      if self.sw_started:
         self.sw_seconds += t
      minutes, seconds = divmod(self.sw_seconds, 60)
      part_seconds = seconds * 100 % 100

      self.root.ids.stopwatch.text = "{:2d} : {:2d}.{:2d}".format(int(minutes), int(seconds), int(part_seconds))
      self.root.ids.time.text = strftime('[b]%H[/b]:%M:%S')

   def on_start(self):
      Clock.schedule_interval(self.update_time, 0)
      
   def start_stop(self):
      self.root.ids.start_stop.text = 'Start' if self.sw_started else 'Stop'
      self.sw_started = not self.sw_started

   def reset(self):
      if self.sw_started:
         self.root.ids.start_stop.text = 'Start'
         self.sw_started = False
      self.sw_seconds = 0
      
StopWatchApp().run()

Output

Since the name of the App class in the above code is StopWatchApp, its "kv" language design script must be named as "StopWatch.kv" and run the program.

Kivy Stopwatch App Example

Press the Start button. The counter will start, showing the time elapsed on the bottom label. The caption changes to Stop. Press it again to stop the clock from running. Clicking the Reset button brings the label to "0".

Kivy Stopwatch App Start
Advertisements