这与另一个问题非常相关.唯一的区别是我是动态添加Ellipse with self.canvas而不是使用Builder(Builder.load_string或Builder.load_file).因此,这里的代码,做工作.当您单击椭圆时,它会移动并更改颜色:
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()
Run Code Online (Sandbox Code Playgroud)
如果我尝试不使用Builder它而做同样的事情,它就不再起作用了:
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()
Run Code Online (Sandbox Code Playgroud)
代码运行,实际调用事件.更重要的是,Widget被移动(即使它在视觉上不清楚),但画布的说明没有更新.
有任何想法吗?
第一个版本有效,因为kv lang自动将画布重新绑定到表达式中的属性,因此这些行:
Color:
rgba: self.r,1,1,1
Run Code Online (Sandbox Code Playgroud)
做的不仅仅是这个:
Color(s.r,1,1,1)
Run Code Online (Sandbox Code Playgroud)
你能做什么,howether,是绑定self.r自动重建你的画布说明.
在 __init__
self.bind(r=self.redraw)
self.bind(pos=self.redraw)
self.bind(size=self.redraw)
Run Code Online (Sandbox Code Playgroud)
并移动
with s.canvas:
Color(s.r,1,1,1)
Ellipse(pos = s.pos, size = s.size)
Run Code Online (Sandbox Code Playgroud)
部分为一个名为的方法redraw,之前使用self.canvas.clear()调用.
完整结果:
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()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2910 次 |
| 最近记录: |