9

これは、この他の質問に非常に関連しています。唯一の違いは、ビルダー (または)with self.canvasを使用する代わりに、楕円を動的に追加していることです。したがって、これが機能するコードです。楕円をクリックすると、楕円が移動して色が変わります。Builder.load_stringBuilder.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()

を使用せずに同じことをしようとすると、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()

コードが実行され、イベントが実際に呼び出されます。さらに、ウィジェットは移動されますが (視覚的にわかりにくい場合でも)、キャンバスの指示は更新されません。

何か案は?

4

1 に答える 1

9

最初のバージョンは、kv lang がキャンバスの再作成を式のプロパティに自動的にバインドするため、次の行で機能します。

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

これ以上のことを行います:

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

ただし、できることは、 self.r をバインドしてキャンバスの指示を自動再構築することです。

__init__

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

を移動します。

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

redrawself.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()
于 2013-06-17T07:52:08.737 に答える