我有以下代码:
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
的值分配变量?
答案 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()