我在我的KV文件中有一个规则我们称之为Foo,它继承自Widget类,我在我的python文件中创建实例:(大多数不相关的细节已被删除)
在python中:
Class Foo(Widget):
x_coord = NumericProperty()
y_coord = NumericProperty()
在Kv:
<Foo>:
pos: self.x_coord + self.parent.bar, self.y_coord() + self.parent.barbar
但是,当我实例化该类时:
new_foo = Foo()
new_foo.x_coord = 7
new_foo.y_coord = 10
[do some more stuff with it]
<a parent widget>.add_widget(new_foo)
我得到一个错误说type object NoneType has no attribute bar
在我看来,KV文件试图在实例化类时立即应用规则,但它还没有父级,因为它还没有被添加到任何东西。我甚至尝试将一个名为parent的临时子类添加到Foo中,该子类具有我引用的所有属性的工作值,这确实停止了错误,但我立即得到了一个新的,因为kivy无法覆盖临时类以添加实际的父级。
我该如何解决这个问题?有没有办法将父母作为参数传递?或者我应该在python中写出规则并将其放在Foo类的init中?
parent
也是一处房产。这意味着您可以创建on_parent
方法,以便在其设置为使用它时调用:
from kivy.app import App
from kivy.properties import NumericProperty
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
class Parent(FloatLayout):
bar = NumericProperty(20)
class Child(Button):
def on_parent(self, obj, parent):
self.pos = (parent.bar, parent.bar)
class MyApp(App):
def build(self):
parent = Parent()
child = Child(text="Test", size_hint=(None, None))
parent.add_widget(child)
return parent
if __name__ == '__main__':
MyApp().run()
如果要在更改父属性时做出反应,可以将方法绑定到on_parent
方法中的父属性:
from functools import partial
from kivy.app import App
from kivy.clock import Clock
from kivy.properties import NumericProperty
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
class Parent(FloatLayout):
bar = NumericProperty(20)
class Child(Button):
def on_parent(self, obj, parent):
self.pos = (parent.bar, parent.bar)
parent.bind(bar=self.update_pos)
def update_pos(self, obj, bar):
self.pos = (bar, bar)
class MyApp(App):
def build(self):
parent = Parent()
child = Child(text="Test", size_hint=(None, None))
parent.add_widget(child)
Clock.schedule_once(partial(self.change_parent_bar, parent), 3)
return parent
def change_parent_bar(self, parent, dt):
parent.bar = 50
if __name__ == '__main__':
MyApp().run()