2013-06-12 7 views
7

Questo è molto correlato a this other question. L'unica differenza è che sto aggiungendo l'Ellipse in modo dinamico con with self.canvas invece di utilizzare il Builder (Builder.load_string o Builder.load_file). Quindi, ecco il codice che funziona. Quando si fa clic nel Ellipse si muove e cambia colore:Come aggiorno il Colore di un ** Ellipse aggiunto dinamicamente (non usando Builder) in base alle proprietà di 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() 

Se provo a fare lo stesso senza usare il Builder, non funziona più:

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() 

Le piste di codice e la l'evento è effettivamente chiamato. Più oltre, il Widget viene spostato (anche se visivamente non è chiaro) ma le Istruzioni della tela non vengono aggiornate.

Qualche idea?

+0

sperimento anche con 'ask_update' e non ha funzionato. –

+0

Mi piace quando una domanda per cui ho bisogno di una risposta è quasi risposta letterale su StackOverflow :) – Nebelhom

risposta

8

La prima versione funziona perché kv lang legano automaticamente la ricreazione di tela per immobili a espressioni, in modo da queste righe:

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

fare più di questo:

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

cosa si può fare, in secondo luogo, è quello di associare self.r per ricostruire automaticamente le istruzioni su tela.

in __init__

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

e spostare la parte

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

ad un metodo chiamato redraw, con una chiamata self.canvas.clear() prima.

risultato pieno:

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

Grazie mille! Stavo iniziando a sospettare che il Builder stesse facendo qualcos'altro oltre ad analizzare la lingua Kivy. –

+1

Beh, tecnicamente è parte del parsing, è solo che il linguaggio kv è stato creato per rendere queste cose più semplici del semplice python. Grazie per il bonus :). – Tshirtman

Problemi correlati