Kivy Tutorials – How to use Clock to schedule widget callback functions

Kivy Tutorials – How to use Clock to schedule widget callback functions

Kivy_clock_schedule

Test Environment

Fedora 31 installed with Kivy

In this tutorial we will see how we can schedule our Child widgets to float in horizontal direction by scheduling the callback function to be called using the Clock functionality package available in Kivy.
 
Before getting into the details of this article lets get some terms outlined here
 

Clock

– This object can be used as a scheduler to call a function once or repeatedly at specified interval periods.

 

Properties

– Kivy properties helps in easy manipulation of widgets in kv langurage. They automatically observe changes and dispatch function or code accordingly.

 
This article is in continuation to our previous article on how to move multiple widgets in kivy . Please have a look at this article for a better understanding.
If you are inerested in reading the article instead of watching the video you can go through the step by step procedure below.
 

 

 

Procedure –

 

Step1: Create a Kivy application named movewidget.py to launch a empty Window

As a first step lets extend App base class and launch an empty Windows with Widget as its root element.

MoveWidget Kivy application
#!/usr/bin/env python

import kivy
kivy.require('1.11.1')

from kivy.app import App
from kivy.uix.widget import Widget

class MyWidget(Widget):
    pass

class MoveWidgetApp(App):
    def build(self):
        mw = MyWidget()
        return mw

if __name__ == '__main__':
    MoveWidgetApp().run()

Step2: Create movewidget.kv file to add Child rectangle widgets to the root widget element

Here in this step we have RectBlock class which will represent our Child Widget which is a rectangle shaped ladded and added two RectBlock instances into the root Widget

MoveWidget kv file
#:kivy 1.11.1

<RectBlock>:
    canvas:
        Rectangle:
            size: 100, 10
            pos: self.pos

<MyWidget>:

    RectBlock:
        pos: root.center_x, 100
    RectBlock:
        pos: root.center_x, 300

Step3: Map the RectBlock Widget with Python property

Here in this step we will try to get a reference of the RectBlock in our Python code using the Object Property. For this first lets give id to each of our Child widget (i.e lad1 and lad2) and map it to Object Properties ladder1 and ladder2.

MoveWidget kv file
#:kivy 1.11.1

<RectBlock>:
    canvas:
        Rectangle:
            size: 100, 10
            pos: self.pos

<MyWidget>:
    ladder1: lad1
    ladder2: lad2

    RectBlock:
        id: lad1
        pos: root.center_x, 100
    RectBlock:
        id: lad2
        pos: root.center_x, 300

Once the necessary changes are done in the kv file we need to modify our python file to include the ObjectProperty in the root Widget class as shown below. Also as we want to move our child widgets in horizontal direction, let us define our function named floatWidget wherein we will put our logic to move the child widgets.

Updated MyWidget Class
class MyWidget(Widget):
    ladder1 = ObjectProperty()
    ladder2 = ObjectProperty()


    def floatWidget(self, dt):
        pass

Step4: Define the logic in floatWidget function to move the Child Widgets in eith left or right direction by 5 units

Let us modify our floatWidget in such a way that ladder1 will be moving in right direction by 5 units and ladder2 will be moving in left direction by 5 unit. Once they reach the borders of the Root Widget, they need to reset their x coordinate such that they look like moving continuously in the horizontal direction.

Updated MyWidget Class with floatWidget function definition
class MyWidget(Widget):
    ladder1 = ObjectProperty()
    ladder2 = ObjectProperty()


    def floatWidget(self, dt):
        self.ladder1.x = self.ladder1.x + 5
        self.ladder2.x = self.ladder2.x - 5

        if self.ladder1.x > self.width:
            self.ladder1.x = 0
            self.ladder1.x = self.ladder1.x + 5
        elif self.ladder2.x < self.x:
            self.ladder2.x = self.width
            self.ladder2.x = self.ladder2.x - 5

Step5: Schedule the floatWidget function to be called at regular interval

In order for our child widgets to actually move, we need to schedule that floatWidget to be called at regular interval to update the Widget postion. For this we will use the Clock class to schedule the callback function as shown below.

Lets modify our python file to import the Clock class and also ObjectProperty to get a reference to the child widget in kv file. Now update our MoveWidget App class to call the floatWidget class using the Clock.schedule_interval function at regular interval

Updated MoveWidget file
#!/usr/bin/env python

import kivy
kivy.require('1.11.1')

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.clock import Clock

class MyWidget(Widget):
    ladder1 = ObjectProperty()
    ladder2 = ObjectProperty()


    def floatWidget(self, dt):
        self.ladder1.x = self.ladder1.x + 5
        self.ladder2.x = self.ladder2.x - 5

        if self.ladder1.x > self.width:
            self.ladder1.x = 0
            self.ladder1.x = self.ladder1.x + 5
        elif self.ladder2.x < self.x:
            self.ladder2.x = self.width
            self.ladder2.x = self.ladder2.x - 5

class MoveWidgetApp(App):
    def build(self):
        mw = MyWidget()
        Clock.schedule_interval(mw.floatWidget, 1.0/60.0)
        return mw

if __name__ == '__main__':
    MoveWidgetApp().run()

With this, we will be able to make our child widgets move in horizontal direction at every 1/60th interval.

Hope you enjoyed reading this article or watching the video. Thank you.