Skip to content Skip to sidebar Skip to footer

AttributeError: 'super' Object Has No Attribute '__getattr__' Error When Using BoxLayout With Several Kv-files In Kivy

As I am very well aware, this question has been asked several times already. But after trying the following solutions: Python - Kivy: AttributeError: 'super' object has no attribu

Solution 1:

The problem is caused by a common error, the ids are relative to a widget, for example in your case let's analyze the expression:

self.ids.ERRORBUTTON

Who is self? self is the instance of RequirementC.

what instance do you have? then let's see the .kv where RequirementC is implemented:

<RequirementC>:
    Button:
        id: REQC
        text: "Press"
        on_release: root.triggerC()

If you notice the only id that has access is to REQC, so the id ERRORBUTTON does not exist for RequirementC.

So which class does the id ERRORBUTTON belong to? So let's review where ERRORBUTTON was created:

 # ...

<ComplexBox>:
    BoxLayout:
        id: layout
        size: root.size
        Button:
            id: ERRORBUTTON
            text: "add"
            on_press: root.addsome()
            on_release: root.testit()
 # ...

As you can see ERRORBUTTON is a id of ComplexBox.


With what was mentioned in the previous part, we already know the cause of the problem. Before giving a solution we first understand a basic principle of programming: A class is an abstraction of a behavior, it must clearly define that you want to expose to the outside (therefore if you check the docs of any library do not document all the methods or all the classes since the idea is to abstract the class, that is to say, that whoever uses that library does not want to know how it works internally with such precision), so it is good to design thinking what methods the classes will have. For example let's say that we create a Person class, this class has certain attributes such as size or weight, what if you think it is necessary to expose how much your heart or brain weighs? Well, no. The same happens in your case.

The solution is to expose the event on_release so that it is part of the RequirementC class, in addition to expose ERRORBUTTON as a property (in my case I do not like to use the ids since they make the code less readable) and then make the connection in a place with common scope.

*.py

# ...

class RequirementC(Widget):
    def __init__(self, **kwargs):
        self.register_event_type('on_release')
        super().__init__(**kwargs)

    def on_release(self):
        pass

# ...

attempt.kv

#:kivy 1.0
#:include attemptsupp.kv
#:include attemptsuppC.kv

# root
<ComplexBox>:
    error_button: ERRORBUTTON # <---
    BoxLayout:
        id: layout
        size: root.size
        Button:
            id: ERRORBUTTON
            text: "add"
            on_press: root.addsome()
            on_release: root.testit()
BoxLayout:
    orientation: 'vertical'
    ComplexBox:
        id: complex_box
    RequirementC:
        on_release: complex_box.error_button.text = "Requirement C met"

attemptsuppC.kv

#:kivy 1.0

<RequirementC>:
    Button:
        id: REQC
        text: "Press"
        on_release: root.dispatch('on_release')

Solution 2:

So after a bit of research i found the answer i was looking for. For those who might also stumble over my problem here it comes:

class RequirementC(Widget):
def triggerC(self):
    presentation.children[1].ids.ERRORBUTTON.text = "Requirement C met"
pass

By going over the children of the presentation it is possible to use the "ids" method.

But for those tempted to use it now i would recommend iterating over the children to find the correct id instead of giving a "hard" reference (children[1]).


Post a Comment for "AttributeError: 'super' Object Has No Attribute '__getattr__' Error When Using BoxLayout With Several Kv-files In Kivy"