I am learning kivy from a book that involves making a paint app. The author at one point introduces new buttons on a canvas class (inherited from Widget) and says that we have to check if the click received by the application on the canvas, also lies on one of its children. In that case, we would neglect the former and act on the latter. I thought of achieving this by looping through self.children, checking if the on_touch_down(touch) member function returns true for any child, and returning from the function if that was the case:
class CanvasWidget(Widget):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.my_color = get_color_from_hex('#FF0000')
self.line_width=2
def on_touch_down(self, touch):
for child in self.children:
if(child.on_touch_down(touch)):
return
with self.canvas:
Color(rgba=self.my_color)
touch.ud['current_line'] = Line(points=(touch.x, touch.y), width=self.line_width)
However, I don't follow and would like to understand his shorthand syntax:
class CanvasWidget(Widget):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.my_color = get_color_from_hex('#FF0000')
self.line_width=2
def on_touch_down(self, touch):
#I don't understand the following line
if Widget.on_touch_down(self, touch):
return
#Widget refers to the parent class (I hope?) how does it check with the
#children?
with self.canvas:
Color(rgba=self.my_color)
touch.ud['current_line'] = Line(points=(touch.x, touch.y), width=self.line_width)
Any clarity is appreciated. Thanks!
The Widget
class is the base class for all the kivy widgets, and it handles the propagation of touch
events to its children via its on_touch_down()
method. Rather than referencing the Widget
base class directly, a better approach is to use the super()
method, like this:
if super(CanvasWidget, self).on_touch_down(touch):
return True
This does the propagation and returns True
(to stop the propagation) if any of the children want the propagation stopped. The code in Widget
that does this is:
for child in self.children[:]:
if child.dispatch('on_touch_down', touch):
return True
Since it does not directly reference the Widget
base class, the super()
method is safer if you decide to change the base class of CanvasWidget
.