pythoncanvaskivy

How do I change the color of a rectangle I have already drawn in Python3 Kivy?


I'm trying to understand how to use Kivy - specifically, the canvas. I have more or less understood how to move around and resize a rectangle I've already drawn, but I can't get the rectangle to change color. Here is my code:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Rectangle, Color


class CanvasWidget(Widget):

    def __init__(self, **kwargs):
        super(CanvasWidget, self).__init__(**kwargs)
        self.click_occured = False
        with self.canvas:
            Color(0, 1, 0)
            self.background = Rectangle(pos=self.pos, size=self.size)
            Color(1, 1, 1)
            self.rect1 = Rectangle(pos=self.pos, size=(self.width/2, self.height/2))
            Color(0, 0, 1)
            self.rect2 = Rectangle(pos=self.pos, size=(self.width/4, self.height/4))
            self.bind(pos = self.update_rect, size = self.update_rect)

    def update_rect(self, *args):
        self.background.pos = self.pos
        self.background.size = self.size
        if not self.click_occured:
            self.rect1.pos = self.pos
        else:
            self.rect1.pos = self.x + self.width/8, self.y + self.height/8
        self.rect1.size = (self.width/2, self.height/2)
        self.rect2.pos = self.pos
        self.rect2.size = (self.width/4, self.height/4)

    def on_touch_down(self, touch):
        self.click_occured = True
        self.rect1.pos = self.x + self.width/8, self.y + self.height/8
        #also, change rect1's color from white to red


class CanvasApp(App):
    def build(self):
        return CanvasWidget()
CanvasApp().run()

In place of the comment at the end of the on_touch_down method, I would like to change rect1's color to red. It has to be a change to the existing rectangle and not the creation of a new one since I want it to remain behind rect2 and I don't want to manually redraw the latter. If possible, I would like to achieve that without using the kv language since I want to be able to create rectangles, labels etc. on the fly while the code is running, and that seems to be inconvenient with the kv language.


Solution

  • An even simpler way without using groups is to just modify the rgb of the Color. First save a reference to the Color in your __init__() method by replacing:

    Color(1, 1, 1)
    

    with:

    self.color1 = Color(1, 1, 1)
    

    Then, in your on_touch_down() method, add the line:

        self.color1.rgb = (1, 0, 0)
    

    See the documentation.