Когда следует связывать атрибуты, заполненные kv-файлом?

test.kv

<RootWidget>:
    test: test

    Label:
        id: test
        text: "some"

test.py

class RootWidget(Widget):
    test = ObjectProperty(None)

    def __init__(self, **kwargs):
        # 1:
        print(self.test)  # None

        # 2:
        def after_tick(*args):
            print(self.test)  # Label object
        Clock.schedule_once(after_tick, 0)

        super().__init__()

Если я попытаюсь связать что-то с self.test прямо внутри __init__ (1) я бы получил AttributeError так как правила kv еще не применяются и self.test is None, Возможный обходной путь - привязка к атрибуту после первой итерации цикла событий (2).

Это решение похоже на клейкую ленту. Есть ли лучший способ?

1 ответ

Решение

Я знаю 3 других способа.

Во-первых, сделать after_tick метод и выполнить его в init:

class RootWidget(Widget):
    test = ObjectProperty(None)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.delayed_init()

    @mainthread
    def delayed_init(self):
        print(self.text)

Во-вторых, используйте встроенный метод, который всегда выполняется после первого кадра цикла:

class RootWidget(Widget):
    test = ObjectProperty(None)

    def add_widget(self, widget, index=0):
        super().add_widget(widget, index)

        if widget.__class__.__name__ == 'Label':
            widget.text = self.test.text

Это полезно, если у вас есть много виджетов одного типа для привязки.

В-третьих, использовать собственность on_x Перезвоните:

class RootWidget(Widget):
    test = ObjectProperty(None)

    def on_test(self, *args):
        print(self.test)
Другие вопросы по тегам