2013-06-12 10 views
7

Jest to bardzo związane z this other question. Jedyna różnica polega na tym, że dynamicznie dodajemy Ellipse przy pomocy with self.canvas zamiast używać Buildera (Builder.load_string lub Builder.load_file). Oto kod , który działa. Po kliknięciu w elipsa porusza się i zmienia kolor:Jak zaktualizować kolor ** dynamicznie dodawanej ** elipsy (bez użycia Buildera) zgodnie z właściwościami Widget Kivy?

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 staram się zrobić to samo bez użycia Builder, 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() 

tras kod i Zdarzenie jest faktycznie wywoływane. Co więcej, widget jest przenoszony (nawet jeśli nie jest to wizualnie jasne), ale instrukcje obszaru roboczego nie są aktualizowane.

Wszelkie pomysły?

+0

ja też eksperymentować z 'ask_update' i to nie działa. –

+0

Podoba mi się, gdy pytanie, na które potrzebuję odpowiedzi, jest prawie dosłownie odpowiedział na stackoverflow :) – Nebelhom

Odpowiedz

8

Pierwsza wersja działa, ponieważ kV lang automatycznie wiązać płótnie rekreacji na właściwości w wyrażeniach, więc te linie:

Color: 
     rgba: self.r,1,1,1 

zrobić więcej niż ten jeden:

Color(s.r,1,1,1) 

co można zrobić, howether, to wiązanie self.r do automatycznego przebudowywania instrukcji canvas.

w __init__

self.bind(r=self.redraw) 
self.bind(pos=self.redraw) 
self.bind(size=self.redraw) 

i przesunąć

with s.canvas: 
     Color(s.r,1,1,1) 
     Ellipse(pos = s.pos, size = s.size) 

częściowo metodę o nazwie redraw, z self.canvas.clear() wywołanie wcześniej.

pełny wynik:

from kivy.app import App 
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): 
     super(CircleWidget, s).__init__(**kwargs) 
     s.bind(r=s.redraw) 
     s.bind(pos=s.redraw) 
     s.bind(size=s.redraw) 
     s.size = [50, 50] 
     s.pos = [100, 50] 

    def redraw(s, *args): 
     s.canvas.clear() 
     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): 
      print "gotcha" 
      s.pos = [s.pos[1], s.pos[0]] 
      s.r = 1.0 

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

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

Dziękuję bardzo! Zaczynałem podejrzewać, że Builder robił coś więcej niż tylko analizowanie języka Kivy. –

+1

Cóż, technicznie jest to część analizy, po prostu język kv jest zbudowany, aby uczynić te rzeczy łatwiejszymi niż zwykły pyton. Dzięki za bonus :). – Tshirtman

Powiązane problemy