Python – adding an on_release action to a kivy button

kivypython

I am trying to refactor the last code sample so that the Button is actually its own class with an on_release action. But my code is failing.

I want to not only refactor it (per my attempt below) but I also need to set the text of the Button to "Clear"

from random import random
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.graphics import Color, Ellipse, Line


class MyPaintWidget(Widget):

    def on_touch_down(self, touch):
        userdata = touch.ud
        userdata['color'] = c = (random(), 1, 1)
        with self.canvas:
            Color(*c, mode='hsv')
            d = 30
            Ellipse(pos=(touch.x - d/2, touch.y - d/2), size=(d, d))
            userdata['line'] = Line(points=(touch.x, touch.y))

    def on_touch_move(self, touch):
        touch.ud['line'].points += [touch.x, touch.y]

class ClearButton(Button):
    def __init__(self, paint_widget):
        self.paint_widget=paint_widget

    def on_release(self, button):
        self.paint_widget.canvas.clear()

class MyPaintApp(App):

    def build(self):
        parent = Widget()
        painter = MyPaintWidget()
        clearbtn = ClearButton(painter)
        parent.add_widget(painter)
        parent.add_widget(clearbtn)

        return parent


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


Best Answer

Without subclassing, you could just do:

class MyPaintWidget(Widget):
    # ... put your previous methods here
    def clear_canvas(self, *largs):
        self.canvas.clear()

class MyPaintApp(App):
    def build(self):
        root = FloatLayout()
        painter = MyPaintWidget()
        cleanbtn.bind(on_release=self.painter.clear_canvas)
        root.add_widget(painter)
        root.add_widget(clearbtn)
        return root

With subclassing, i would prefer to go with Kv langage:

from kivy.lang import Builder

Builder.load_string('''
<ClearButton>:
    text: "Clear"
    on_release: app.painter.canvas.clear()
''')

class ClearButton(Button):
    pass

class MyPaintApp(App):
    def build(self):
        parent = Widget()
        painter = MyPaintWidget()
        clearbtn = ClearButton()
        parent.add_widget(painter)
        parent.add_widget(clearbtn)
        return parent
Related Topic