2013-06-12 16 views
7

Điều này rất liên quan đến this other question. Sự khác biệt duy nhất là tôi thêm động Ellipse động với with self.canvas thay vì sử dụng Builder (Builder.load_string hoặc Builder.load_file). Vì vậy, đây là mã số hoạt động. Khi bạn nhấp chuột vào Ellipse nó di chuyển và thay đổi màu:Làm cách nào để cập nhật Màu của ** được thêm động ** Ellipse (không sử dụng Trình dựng) theo thuộc tính 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() 

Nếu tôi cố gắng làm như vậy mà không sử dụng Builder, nó không hoạt động nữ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() 

Mã chạy và sự kiện thực sự được gọi. Hơn thế nữa, Widget được di chuyển (ngay cả khi nó không rõ ràng) nhưng Hướng dẫn của canvas không được cập nhật.

Bất kỳ ý tưởng nào?

+0

Tôi cũng thử nghiệm với 'ask_update' và nó đã không làm việc. –

+0

Tôi thích nó khi một câu hỏi tôi cần một câu trả lời cho là gần như nguyên văn trả lời trên stackoverflow :) – Nebelhom

Trả lời

8

Phiên bản đầu tiên làm việc vì kv lang tự động ràng buộc giải trí vải để tài sản trong biểu thức, vì vậy những dòng này:

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

làm nhiều hơn thế này một:

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

những gì bạn có thể làm, howether, là để ràng buộc self.r để tự động xây dựng lại các hướng dẫn canvas của bạn.

trong __init__

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

và di chuyển Phần

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

đến một phương thức có tên redraw, với một self.canvas.clear() gọi trước.

kết quả đầy đủ:

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

Cảm ơn bạn rất nhiều! Tôi đã bắt đầu nghi ngờ rằng Builder đã làm một cái gì đó khác hơn là chỉ phân tích ngôn ngữ Kivy. –

+1

Vâng, về mặt kỹ thuật, nó là một phần của phân tích cú pháp, nó chỉ là ngôn ngữ kv được xây dựng để làm cho những thứ này dễ dàng hơn so với python đơn giản. Cảm ơn vì tiền thưởng :). – Tshirtman

Các vấn đề liên quan