Kivy - Clock



The Clock object in Kivy framework is a global event dispatcher. It is used to schedule and trigger events at specific intervals. To schedule an event for repeated or one-time occurrence, it is bound to a callback function. You can get the time elapsed between the scheduling and the calling of the callback via the "dt" argument, which is the delta-time.

The Clock object is defined in the "kivy.clock" module. It consists of methods such as "schedule_once()" and "schedule_interval()" to register functions or methods to be called after a certain delay or at regular intervals. This mechanism is useful for handling timed events, animation updates, and other recurring tasks in your app.

Both the functions "schedule_interval()" and "schedule_once()" have two arguments; a callback and the time interval in seconds.

from kivy.clock import Clock

def clock_callback(dt):
   "Clock event occurred"
   
# call clock_callback every 2 seconds
Clock.schedule_interval(clock_callback, 2)

# call clock_callback in 5 seconds
Clock.schedule_once(clock_callback, 5)

The default value of timeout dt argument is 0. Hence, to call the callback function as early as possible, set the second argument to schedule events to 0 or let the default value be used by not giving using the argument.

Clock.schedule_once(my_callback)

Using a timeout of "-1" causes the event to occur before the next frame, and setting it to 0 causes the event to occur after the next frame.

Triggered Events

The Clock object can trigger a clock event with the use of the following functions −

  • schedule_interval(callback, timeout) − This function schedules an event to be called every specified seconds. The function returns a ClockEvent object. Call ClockEvent.cancel() on the returned event to unscheduled the event.

  • schedule_once(callback, timeout=0) − This function schedules an event for one-time execution in specified seconds, and returns ClockEvent object. If timeout is unspecified or 0, the callback will be called after the next frame is rendered. To cancel the event, call ClockEvent.cancel() on the returned event.

  • create_trigger(callback, timeout=0) − This function creates a Trigger event. Unlike the other two functions, the event is not scheduled automatically, you need to call it. Like the other two, cancel the event before it is executed, by calling ClockEvent.cancel(). To schedule it again, simply call the event (event()).

The create_trigger() function has the following Parameters −

  • callback − A callback to be executed. from kivy. It takes a timeout parameter to specify how long to wait before calling the callback.

  • interval − a bool parameter indicates whether the callback should be called once (False) or repeatedly.

from kivy.clock import Clock
def clock_callback(dt):
   "Clock event occurred"
triggerevent = Clock.create_trigger(clock_callback, 5)
triggerevent()

To unscheduled an event created by either of these ways, use event.cancel() or event.unschedule() methods.

Example

The code given below runs a countdown timer on the Kivy application window. The "kv" script puts a TextInput box, a label and a button in onecolumn gridlayout.

<clockwidget>:
   GridLayout:
      cols:1
      size:root.size
      TextInput :
         font_size : '30pt'
         id:t1
         halign:'center'
         valign:'center'
      Label:
         id: l1
         text : 'Current Value: '
         font_size : '20pt'
      
      Button :
         id:b1
         text : 'Start Countdown'
         font_size:20

The layout class clockwidget inherits GridLayout and binds the command button to a method that schedules a periodic event to occur after every one second.

Each time the callback is invoked, the label shows decrementing number, starting from the value entered by the user in the text box. As it reaches 0, the event is unscheduled by its cancel() method.

class clockwidget(GridLayout):
   def __init__(self, *args):
      super(*args).__init__()
      self.ids.b1.bind(on_press=self.showtime)

   def countdown(self, dt):
      if self.val==0:
         self.ids.l1.text="Countdown Stopped"
         self.ids.l1.color=[1,0,0]
         self.ev.cancel()
         self.ids.b1.disabled=False
      else:
         self.ids.l1.text="Current Value: {}".format(self.val)
         self.ids.l1.color=[1,1,1]
         self.val=self.val-1
         
   def showtime(self, *args):
      self.val=int(self.ids.t1.text)
      self.ev=Clock.schedule_interval(self.countdown, 1)
      self.ids.b1.disabled=True

The complete code for this exercise is given below −

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.clock import Clock
from kivy.core.window import Window

Window.size = (720, 400)

class clockwidget(GridLayout):
   def __init__(self, *args):
      super(*args).__init__()
      self.ids.b1.bind(on_press=self.showtime)
      
   def countdown(self, dt):
      if self.val == 0:
         self.ids.l1.text = "Countdown Stopped"
         self.ids.l1.color = [1, 0, 0]
         self.ev.cancel()
         self.ids.b1.disabled = False
      else:
         self.ids.l1.text = "Current Value: {}".format(self.val)
         self.ids.l1.color = [1, 1, 1]
         self.val = self.val - 1
   def showtime(self, *args):
      self.val = int(self.ids.t1.text)
      self.ev = Clock.schedule_interval(self.countdown, 1)
      self.ids.b1.disabled = True
      
class clockdemoapp(App):
   def build(self):
      w = clockwidget()
      w.cols = 1
      return w
      
clockdemoapp().run()

Output

When you run this program, it will show the following app window. Enter the value for the countdown timer and click the "start" button.

Kivy Clock

The label starts updating, decrementing the number of countdown value.

Kivy Clock Start

As it reaches "0", the button is enabled again.

Kivy Clock Stop
Advertisements