Kivy обратный вызов пользовательского виджета вызов из идентификаторов рейса - PullRequest
0 голосов
/ 18 мая 2018

Я пытаюсь вызвать пользовательский метод виджета из его идентификаторов.

Но я получил AttributeError: 'LabelBox' object has no attribute 'change_first_text'.

Самый простой рабочий пример можно найти здесь с помощьюФайл PanelApp.py:

from kivy.app import App
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder

Builder.load_file("panel.kv")

class LabelBox(BoxLayout):
    def __init__(self, *args, **kwargs):
        super(LabelBox, self).__init__(*args, **kwargs)

    def change_first_text(self, text):
        self.ids.first.text = text

class ButtonList(BoxLayout):
    pass

class Test(TabbedPanel):
    pass


class TabbedPanelApp(App):
    def build(self):
        self.test = Test()
        self.btn_list = ButtonList()
        self.vbox = BoxLayout(orientation="vertical")
        self.vbox.add_widget(self.btn_list)
        self.vbox.add_widget(self.test)
        return self.vbox

    def change_first(self, value):
        print("Button clicked and new value is: '{}'".format(value))
        self.test.ids.lbs.change_first_text(value)


if __name__ == '__main__':
    TabbedPanelApp().run()

и файл panel.kv:

<ButtonList@ButtonList>:
    orientation: "horizontal"
    Button:
        text: "change fisrt to me"
        on_press: app.change_first(self.text)
    Button:
        text: "change two to me"

<LabelBox@BoxLayout>:
    Label:
        id: first
        text: "first"
    Label:
        id: two
        text: "two"

<Test>:
    size_hint: .5, .5
    pos_hint: {'center_x': .5, 'center_y': .5}
    do_default_tab: False

    TabbedPanelItem:
        text: 'first tab'
        LabelBox:
            id: lbs

Вызов сценария вызывает ошибку времени выполнения, которую я не могу понять.Есть ли у вас какие-либо подсказки о том, как управлять таким обратным вызовом события через приложение?

1 Ответ

0 голосов
/ 18 мая 2018

Проблема в вашем случае заключается в том, что вы создаете 2 класса с именем LabelBox:

1.

class LabelBox(BoxLayout):
    def __init__(self, *args, **kwargs):
        super(LabelBox, self).__init__(*args, **kwargs)

    def change_first_text(self, text):
        self.ids.first.text = text

2.

<LabelBox@BoxLayout>:
    Label:
        id: first
        text: "first"
    Label:
        id: two
        text: "two"

Я понимаючто вы хотите иметь только класс, поэтому уместно делать создание с наследованием в .py и только с реализацией потомков в .kv.Решение состоит в том, чтобы изменить delete @BoxLayout в .kv

<LabelBox>:
    Label:
        id: first
        text: "first"
    Label:
        id: two
        text: "two"
...