我在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文件在实例化该类后立即尝试应用该规则,但它尚未获得父项,因为尚未将其添加到任何内容。我什至尝试向Foo添加一个名为parent的临时子类,该子类具有我所引用的所有属性的工作值,但这确实阻止了错误,但是我立即得到了一个新的子类,因为kivy无法覆盖临时类以添加实际的父类
我该如何解决?有没有一种方法可以通过父母作为参数?还是我应该在python中写出规则,然后将其放在Foo类的init中?
答案 0 :(得分:0)
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()