将Widget添加到kv动态类中继承类的子级

问题描述 投票:1回答:2

如果我有一个动态定义的类,如下所示:

<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()

这是一个完整的验证示例,它不起作用

python kivy kivy-language
2个回答
1
投票

.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)

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类。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.