如果我有一个动态定义的类,例如:
<Foo@BoxLayout>:
orientation: "vertical"
...some other child widgets...
BoxLayout:
id: target
orientation: "horizontal"
...other children...
我如何创建一个继承自此的类,唯一的变化是使用BoxLayout
添加到id: target
的附加小部件?
我试图将动态类更改为规则并在python中定义类:
class Foo(BoxLayout):
pass
class EditedFoo(Foo):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.ids["target"].add_widget(<the widget I want to add>, index=0)
但是__init__
函数(和on_parent
函数中的id是空的。
有什么方法可以在不重新定义整个类的情况下完成此操作吗?
编辑:
from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
kv = """
BoxLayout:
EditedFoo:
<Foo>:
orientation: "vertical"
BoxLayout:
id: target
orientation: "horizontal"
"""
class TestApp(App):
def build(self):
return Builder.load_string(kv)
class Foo(BoxLayout):
pass
class EditedFoo(Foo):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.ids["target"].add_widget(Button(text="hello"), index=0)
TestApp().run()
这是无法正常工作的完整示例
答案 0 :(得分:1)
执行Python代码后,.kv
文件中的代码将初始化。
因此,您的EditedFoo(Foo)
将首先从Python代码继承Foo(BoxLayout)
,然后将重新声明Foo
文件中的.kv
。
最好的方法是将Foo(BoxLayout)
的初始属性放在Python代码中,然后在Foo
中继承.kv
,例如<EditedFoo@Foo>
例如,
在.py
中:
class Foo(BoxLayout):
greeting = "hi"
在.kv
中:
<EditedFoo@Foo>
greeting: "Goodbye World"
Foo:
id: root_foo
Button:
text: root_foo.greeting
EditedFoo:
id: foo1
Label:
text: foo1.greeting
EditedFoo:
id: foo2
greeting: "Hello Another World"
Button:
text: foo2.greeting
通过这种方式,您可以在EditedFoo
继承的.kv
中使用Foo
类。
答案 1 :(得分:1)
.kv代码实现了用Python创建的类,因此可以理解,它将在构造函数完成执行后添加,因此id在构造函数中为空,一种技巧是使用Clock来调用函数渲染整个窗口后一会儿,因为那时id不会为空:
# ...
from kivy.clock import Clock
# ...
class EditedFoo(Foo):
def __init__(self, **kwargs):
super().__init__(**kwargs)
Clock.schedule_once(self.callback)
def callback(self, *args):
self.ids["target"].add_widget(Button(text="hello"), index=0)