AttributeError: 'super' Object Has No Attribute '__getattr__' Error When Using BoxLayout With Several Kv-files In Kivy
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"