Kivy Tutorials – How to create multiple widgets in Kivy UI and bind them to touch event for moving them

Test Environment
Fedora 31 with kivy installed
What is Kivy –
Kivy is a Python framework which is used to develop multi touch software application for various devices like Andriod, IOS, Tablets and Desktops.
In this video we will try to build a very basic Kivy application and include few Canvas Widgets. Once the Widgets are placed onto our Root Widgets, we will try to bind the touch events for these widgets in such a way that they will help us grab any particular instance of Canvas Widget and drag it as per our convenience.
Before going into the details of the example lets get some basic information about a few terms
on_touch_down
– This is the event that gets triggered when a particular widget is clicked
on_touch_move
– This is the event that gets triggered when a particular widget is clicked and dragged without releasing the widget.
on_touch_up
– This is the event that gets triggered when a particular widget is released.
If you are interested in reading instead of watching the video, i have include the step by step procedure for the same below the video.
Procedure –
Step1: Create application named MoveWidgetApp which will launch an empty Window with Widget as the root element.
Here we are going to use Widget element and extend it using our Custom Widget Class MyWidget which will be passed as the root Widget when the application is launched
MoveWidget Kivy application |
---|
[admin@fed31 movewidget]$ cat movewidget.py #!/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): my = MyWidget() return my if __name__ == '__main__': MoveWidgetApp().run() |
Step2: Create movewidget.kv file to add two child rectangle widgets with a particular size
Here we have defined a new class named MoveWidget in which we have defined canvas to draw the rectangle widget. This child widget we will be adding to our root widget ie. MyWidget as shown below.
moveWidget kv file |
---|
[admin@fed31 movewidget]$ cat movewidget.kv #:kivy 1.11.1 <MoveWidget>: canvas: Rectangle: size: 100, 50 pos: self.pos <MyWidget>: MoveWidget: pos: 100, 100 MoveWidget: pos: 100, 300 |
We also need to define our MoveWidget class in our main application file as shown below.
MoveWidget Kivy application |
---|
[admin@fed31 movewidget]$ cat movewidget.py #!/usr/bin/env python import kivy kivy.require('1.11.1') from kivy.app import App from kivy.uix.widget import Widget class MoveWidget(Widget): pass class MyWidget(Widget): pass class MoveWidgetApp(App): def build(self): my = MyWidget() return my if __name__ == '__main__': MoveWidgetApp().run() |
Step3: Define and Bind the Widget events like touch, move and release
Until Step2, we have created our root Widget Application with two Child Widget of Rectangle shape added. Now, we will define the three Widget functions that are.
on_touch_down, on_touch_up and on_touch_move in such a way that we can drag our Child Widgets in the horizontal direction individually.
We need to initialize our MoveWidget class using __init__ if we want to define our UI and call super as shown below.
on_touch_down – In this function we need to first validate touch points whether they are within the Widget Collide area. If that condition is True, we are grabbing that Widget instance using touch.grab(self)
on_touch_up – In this function we are checking whether the current widget grabbed and if that condition is True, we are ungrabbing that current Widget and returing True
on_touch_move – In this function once the Widget is grabbed and if we are moving the Widget in horizontal direction we are updating the Widget x coordinate in such a way that it moves in the direction where touch is being dragged.
We also need to make sure to return the touch postion to the Widgets parent class in case these events are not handled here in our Custom MoveWidget class by using super.
We need to modify our MoveWidget class as shown below
MoveWidget Kivy application with touch event functions |
---|
class MoveWidget(Widget): def __init_(self, **kwargs): super(MoveWidget, self).__init__(**kwargs) def on_touch_down(self, touch): if self.collide_point(*touch.pos): #print("Child Widget touched") touch.grab(self) return True return super(MoveWidget, self).on_touch_down(touch) def on_touch_up(self, touch): if touch.grab_current is self: touch.ungrab(self) return True super(MoveWidget, self).on_touch_up(touch) def on_touch_move(self, touch): if touch.grab_current is self: if touch.x < self.width: self.x = touch.x else: self.x = touch.x - self.width return True return super(MoveWidget, self).on_touch_move(touch) |
Now, we have our two Child Widgets which we can move them in horizontal direction individually using the touch events.
Hope you enjoyed reading this article or watching the video. Thank you..
Leave a Reply
You must be logged in to post a comment.