1

I'm trying to call a custom widget method from its ids.

But I received an AttributeError: 'LabelBox' object has no attribute 'change_first_text'.

As a simple as possible working example can be found here with the PanelApp.py file:

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

and the panel.kv file:

<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

Calling the script cause a runtime error that I can't understand. Have you any clue on how to manage such event callback through the application?

1 Answer 1

2

The problem in your case is that you are creating 2 classes called 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"

I understand that you only want to have a class so it is appropriate to do the creation with the inheritance in the .py and only the implementation of children in the .kv. The solution is to change delete @BoxLayout in the .kv

<LabelBox>:
    Label:
        id: first
        text: "first"
    Label:
        id: two
        text: "two"
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! It's works. I totally missed the "details" of @BoxLayout in the .kv file used to create a new class. Spent hours looking for this issue :-(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.