2016-11-16 12 views
1

私がしたいのは、リストにウィジェットの束を追加して後でキャンバスに各ウィジェットを描画できるようにすることです。私は、ループを使用することを考えている(例えば、ウィジェットのウィジェットの場合):そしてその描画関数を呼び出す。私は、それぞれのウィジェットを互いに依存しないので、それぞれのウィジェットをそれ自身のエンティティにしたい(私が1つを削除することを選択した場合、他は削除されない)。私はあなたがリストにオブジェクトを追加し、彼らを呼び出すことができますのように、これは、オブジェクトのための定期的なPythonで可能である知っているkivy/pythonでウィジェットを追加するにはどうすればいいですか?

from kivy.app import App 

from kivy.uix.widget import Widget 

from kivy.graphics import Color, Ellipse, Line 

class YellowDot(Widget): 

    def draw(self): 
     with self.canvas: 
      Color(1,1,0) 
      Ellipse(pos=(500, 500), size=(50,50)) 

class TestApp(App): 

    def build(self): 
     game=YellowDot() 
     game.draw() 
     return game 

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

:これまでのところ、私は最低限(それが唯一の1つの黄色の点を描画する)ためのコードを持っていますそれぞれの機能。ウィジェットをリストなどに追加することは可能ですか?あなたは、ウィジェットがガベージコレクション(メモリから解放)か、しないことができるようにしたい場合は

+0

にcivy 'add_widget'でウィジェットを表示するには親ウィジェットが使用されます。また、スタイリングにkv言語を使用することをお勧めします。変化する属性を参照する際に問題は解決します。 – syntonym

+0

ウィジェットは普通のpythonオブジェクトなので、ウィジェットはあなたが望むものを何でも(例えば、リストに格納したり、辞書に入れたり、関数に与えるなど)行うことができます。 – syntonym

答えて

0

あり、2つの方法があり、どの選択することが依存:

from kivy.app import App 
from kivy.uix.widget import Widget 
from kivy.weakproxy import WeakProxy 
from kivy.uix.boxlayout import BoxLayout 
from kivy.graphics import Color, Ellipse, Line 
from random import randint as r 

class Dot(Widget): 

    def __init__(self, dot_color=None, **kwargs): 
     super(Dot, self).__init__(**kwargs) 

     if not dot_color: 
      raise Exception('No color available!') 
     self.dot_color = dot_color 

     # call draw automatically 
     self.draw() 

    def draw(self): 
     with self.canvas: 
      Color(*self.dot_color) 
      Ellipse(pos=self.pos, size=self.size) 

class TestApp(App): 

    def build(self): 
     colors = ((1, 0, 0), 
        (0, 1, 0), 
        (0, 0, 1)) 

     do_weak_referencing = False # change to True for weakrefs 
     if do_weak_referencing: 
      # get the class for weak referencing 
      # variant 1 
      wp = WeakProxy 
      self.dots = [ 
       WeakProxy(
        Dot(dot_color=dc, 
         pos=(r(100, 500), r(100, 500))) 
       ) for dc in colors] 
     else: 
      # variant 2 
      self.dots = [ 
       Dot(dot_color=dc, 
        pos=(r(100, 500), r(100, 500)) 
       ) for dc in colors] 

     box = BoxLayout() 
     for dot in self.dots: 
      # where will our dot be? 
      print(dot.pos) 
      box.add_widget(dot) 

     # what the list look like? 
     print(self.dots) 
     return box 

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

注オブジェクトが入っている場合にリストにはWeakProxyとして追加され、どこにも追加されていない場合は収集されます。後でアクセスしようとすると、それが利用できないというエラーが発生します(変形例1)。

しかし、強い参照のためにまっすぐ進むことを選択した場合、オブジェクトはself.dotsリストからポップアップされない限り収集されません。

ドットがどこにあるかあなたが見ることができるように私は、__init__に直接self.draw()を入れて、あなたはそれを削除して、例えばApp.dotsから直接呼び出すことができます。

app = App.get_running_app() 
app.dots[0].draw() 
# tada! 
関連する問題