如果我有一个动态定义的类,如下所示:
<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()
这是一个完整的验证示例,它不起作用
.kv代码实现了在Python中创建的类,因此可以理解它将在构造函数完成执行后添加,因此构造函数中的id将为空,一个技巧是使用将在稍后调用函数的Clock渲染整个窗口,因为那时ids不会是空的:
# ...
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)
执行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
类。