在kvlang中访问Kivy布局大小

时间:2017-02-08 03:43:37

标签: python kivy typeerror nonetype kivy-language

我有以下代码:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout


class TestGUI(BoxLayout):
    pass


class TestApp(App):
    def build(self):
        return TestGUI()


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

和相应的.kv文件:

#:kivy 1.9.1

<TestGUI>:
    temp_size: (0.5 * x for x in self.size)
    canvas.before:
        Color:
            rgba: (1, 0, 0, 1)
        Rectangle:
            size: self.temp_size

代码无法运行,抛出:

TypeError: 'NoneType' object is not iterable

由于kv文件中的最后一行代码。宣布self.size时似乎没有初始化temp_size,但这引发了一些问题。

  • 为什么在声明self.size temp_size是否为NoneType对象时,我可以通过size: (0.5 * x for x in self.size)进行迭代?

  • 另外,为什么当我用self.size替换最后一行而不是使用变量时代码完全正常?

  • 此外,我如何规避此问题并根据form的值分配变量?

1 个答案:

答案 0 :(得分:1)

这里发生的事情基本上是这样的:

[x for x in None]

为什么就像您可以阅读此bug report一样。这是因为canvas尚不可用,而且在创建之后似乎计算了属性,因此 - 如果没有canvas ,然后值==垃圾。

要修复它,你必须在画布本身这样做,而不是在属性中的外部,因为画布首先构建:

<TestGUI>:
    canvas.before:
        Color:
            rgba: (1, 0, 0, 1)
        Rectangle:
            size: (0.5 * x for x in self.size)

我不确定最后一个问题是什么意思,但我认为它可能是在 canvas已经可用之后使用属性,或者使用的是Config如果您打算使用Window而不是Widget尺寸,或者在__init__中设置该属性,稍后在kv中使用它。

后者对你来说可能是最好的,但不要忘记:

  • 使用一些值(ListProperty([0, 0]))进行初始化,否则Rectangle将会删除该应用
  • 出于继承原因使用super()

示例:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty
Builder.load_string('''
<TestGUI>:
    canvas.before:
        Color:
            rgba: (1, 0, 0, 1)
        Rectangle:
            size: self.temp_size
''')


class TestGUI(BoxLayout):
    temp_size = ListProperty([0, 0])

    def __init__(self, **kwargs):
        super(TestGUI, self).__init__(**kwargs)
        print(self.size)
        self.temp_size = [0.5 * x for x in self.size]


class TestApp(App):
    def build(self):
        return TestGUI()


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