Jak zaktualizować kolor ** dynamicznie dodanej ** Ellipse (nie używając Buildera) zgodnie z właściwościami Widget Kivy?

Jest to bardzo związane zto inne pytanie. Jedyną różnicą jest to, że dodaję Ellipse dynamicznie za pomocąwith self.canvas zamiast używać Buildera (Builder.load_string lubBuilder.load_file). Oto kodto działa. Po kliknięciu elipsy porusza się i zmienia kolor:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty
from kivy.graphics import Color, Ellipse

Builder.load_string("""
<CircleWidget>:
    canvas:
        Color:
            rgba: self.r,1,1,1
        Ellipse:
            pos: self.pos
            size: self.size
""")

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

    def on_touch_down(s, touch):
        if s.collide_point(touch.x,touch.y):    
            s.pos = [s.pos[1],s.pos[0]]     # this works
            s.r = 1.0                       # this also works

class TestApp(App):
    def build(s):
        parent = Widget()
        parent.add_widget(CircleWidget())
        return parent

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

Jeśli spróbuję zrobić to samo bez użyciaBuilder, to już nie działa:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty
from kivy.graphics import Color, Ellipse

class CircleWidget(Widget):
    r = NumericProperty(0)
    def __init__(s, **kwargs):
        s.size= [50,50]
        s.pos = [100,50]
        super(CircleWidget, s).__init__(**kwargs)
        with s.canvas:
            Color(s.r,1,1,1)
            Ellipse(pos = s.pos, size = s.size)

    def on_touch_down(s, touch):
        if s.collide_point(touch.x,touch.y):    
            s.pos = [s.pos[1],s.pos[0]]     # This doesn't work anymore
            s.r = 1.0                       # Neither do this

class TestApp(App):
    def build(s):
        parent = Widget()
        parent.add_widget(CircleWidget())
        return parent

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

Kod działa, a zdarzenie jest rzeczywiście wywoływane. Co więcej, Widget jest przenoszony (nawet jeśli jest wizualnie niewyraźny), ale Instrukcje płótna nie są aktualizowane.

Jakieś pomysły?

questionAnswers(1)

yourAnswerToTheQuestion