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

Test Environment
Fedora 31 installed with Kivy
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.
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.
Leave a Reply
You must be logged in to post a comment.