如果可以在kivy / python中添加小部件,如何将其添加到列表中?

时间:2016-11-16 03:57:24

标签: android python ios widget kivy

所以我想要做的是将一堆小部件添加到列表中,稍后,可以在画布上绘制每个小部件。我正在考虑使用循环(例如,在小部件中的小部件:),然后调用它们的绘图函数。我希望每个小部件都是它自己的实体,因为它们不相互依赖(如果我选择删除一个,其他小部件也不会被删除)。到目前为止,我有最低限度的代码(它只绘制1个黄点):

Get

我知道这可以在常规python中用于对象,因为你可以将对象添加到列表并调用它们各自的函数。是否可以在列表中添加小部件或类似的东西?

1 个答案:

答案 0 :(得分:0)

有两种方法可供选择取决于您是否希望小部件能够被垃圾收集(无内存):

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列表中弹出,否则不会收集该对象。

我将self.draw()直接放在__init__中,以便您可以看到这些点的位置,但您可以将其删除并直接从App.dots调用它,例如:

app = App.get_running_app()
app.dots[0].draw()
# tada!