Search code examples
pythonkivykivy-languagekivymd

Kivy (MD) - How do you access class properties when you separate the Kivy classes?


Apologies if I got my terminology mixed up. I put together this example to show my problem. I want to access the text property of the label, which I put in the LabelOne class. With the .py:

from kivy.lang import Builder

from kivymd.app import MDApp
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.label.label import MDLabel


class LabelOne(MDLabel):
    pass

class LayoutEx(MDBoxLayout):
    pass

class MainApp(MDApp):

    def build(self):
        self.theme_cls.theme_style = 'Light'
        self.theme_cls.primary_palette = 'Blue'

        return Builder.load_file('figure_out_ids.kv')

    def on_start(self):
        self.root.ids.label_one.text = 'changed'


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

I access the text property of the label with the on_start method. Now when I structure my .kv code like this:

LayoutEx:
    id: layout_ex

    LabelOne:
        id: label_one
        text: 'test'
        halign: 'center'

the on_start method works perfectly and I am able to manipulate label_one.text in python. However, what I actually want to be able to do is separate the LabelOne class in the .kv file and write it like this:

<LabelOne>:
    id: label_one
    text: 'test'
    halign: 'center'

LayoutEx:
    id: layout_ex

    LabelOne:

and still be able to call the label from the MainApp on_start method, but this gives: AttributeError: 'super' object has no attribute '__getattr__' error. Now from looking around the internet, I understand that I have to change self.root.ids.label_one.text = 'changed' into something like self.parent1.parent2.ids.label_one.text, but I've failed to understand what variables need to be placed in the parent1 and parent2 spots. I've been stuck on this all day and I hope that someone can help me understand the process here. I suspect it is my lack of fundamental python knowledge that is causing the issue. Thank you very much in advance!!


Solution

    1. there is no thing self.parent1.parent2. in kivy you can use parent.parent.... until you reach the required widget

    2. the best solution for this situation is to make the id of the LabelOne inside the root widget and you can put all the other LabelOne properties in the LabelOne class like this

    <LabelOne>:
        
        text: 'test'
        halign: 'center'
    
    LayoutEx:
        id: layout_ex
    
        LabelOne:
            id: label_one
    
    

    and then you can access any of LabelOne propertys using python app.root.label_one in the kv file and python self.root.ids.label_one in the MainApp class you can find many solution for this but this the best one