welu
welu

Reputation: 339

How to change color of Ellipse when pressing a button on Kivy?

I am stuck on how to change the color of some ellipse elements dynamically; I put all generated points into a list. Then I want to change their color:

In fact, using params to change is seems not to be a good idea for that

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

points = []

class MyPaintWidget(Widget):
    def __init__(self, **kwargs):
            self.size= [50,50]
            self.pos = [100,50]
            self.r = 0
            super(MyPaintWidget, self).__init__(**kwargs)

    def on_touch_down(self, touch):
        color = (self.r, 1, 1)
        with self.canvas:
            Color(*color, mode='hsv')
            d = 30.
            pts = Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
            points.append(pts)

class MyPaintApp(App):

    def build(self):
        parent = Widget()
        self.painter = MyPaintWidget()
        clearbtn = Button(text='Change Color')
        clearbtn.bind(on_release=self.change_color)
        parent.add_widget(self.painter)
        parent.add_widget(clearbtn)
        return parent

    def change_color(self, obj):
        print(len(points))
        points[0].r = 0.2 <= Error !

Upvotes: 1

Views: 943

Answers (1)

John Anderson
John Anderson

Reputation: 38947

Your on_touch_down() method is adding graphics instructions to the canvas with every touch. In order to change the color of all the Ellipses, you would need to change each of those Color commands. That could be done, but a simpler approach is to just to clear the canvas, and add new graphics instructions to redraw all the Ellipses with the new color. Here is a modified version of your code that does that:

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


class MyPaintWidget(Widget):
    def __init__(self, **kwargs):
        super(MyPaintWidget, self).__init__(**kwargs)
        self.size= [50,50]
        self.pos = [100,50]
        self.d = 30
        self.r = 0          # the hue
        self.ellipses = []  # a list of points for the Ellipses

    def redraw(self):
        # method to clear the canvas and redraw all the Ellipses with new hue
        self.canvas.clear()
        with self.canvas:
            Color(self.r, 1, 1, mode='hsv')
            for pt in self.ellipses:
                Ellipse(pos=pt, size=(self.d,self.d))

    def on_touch_down(self, touch):
        # just add a new position to the list and redraw
        self.ellipses.append((touch.x - self.d / 2, touch.y - self.d / 2))
        self.redraw()


class MyPaintApp(App):
    def build(self):
        parent = Widget()
        self.painter = MyPaintWidget()
        clearbtn = Button(text='Change Color')
        clearbtn.bind(on_release=self.change_color)
        parent.add_widget(self.painter)
        parent.add_widget(clearbtn)
        return parent

    def change_color(self, obj):
        print(len(self.painter.ellipses))
        self.painter.r = 0.2  # change the hue
        self.painter.redraw() # and redraw


MyPaintApp().run()

Upvotes: 1

Related Questions