Search code examples
pythonpython-3.xkivykivy-languagekivymd

Use ids in on_start() function kivy Python


So I am building a general knowledge quiz game, and upon startup of the app, the player's score (that is kept in a .txt file) should be displayed in a label.

I've tried to use the on_start() function for this, but I can't seem to access the ids of the 'score' label. Here is the line of my code that gives the error:

self.root.get_screen("home_screen").ids.score.text = str(playerScore)

I receive the following error:

AttributeError: 'super' object has no attribute '__getattr__'

Here is my full code:

#main.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen

Builder.load_file('design.kv')

class RootWidget(ScreenManager):
    pass

class HomeScreen(Screen):
    pass

class MainApp(App):

    def build(self):
        return RootWidget()

    def on_start(self):
        with open("score.txt", "r") as f:
            playerScore = f.readline()
        
        self.root.get_screen("home_screen").ids.score.text = str(playerScore)




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

and

#design.kv    

<HomeScreen>:
GridLayout:
    cols: 1

    GridLayout:
        cols: 2

        Button:
            id: infoButton
            text: "Wiki"

        Label:
            id: score

    GridLayout:
        cols: 1

        Label:
            id: Question
            text: "Question"

        Button:
            id: Button1
            text: "Option 1"

        Button:
            id: Button1
            text: "Option 2"

        Button:
            id: Button1
            text: "Option 3"

        Button:
            id: Button1
            text: "Option 4"

<RootWidget>:
HomeScreen:
    name: "home_screen"

and also a 'score.txt' file with only - '100' inside.

Thank you.


Solution

  • Your approach was right. I am not sure what you want your layout to look like, but you made two mistakes:

    • Your .kv code was missing indentations after your class definitions
    • Even with indentations, you placed three GridLayouts on top of each other. One approach would be to put these three GridLayouts inside a BoxLayout, or just structurize your GridLayout in another way (e.g. pack all widgets inside one GridLayout). Basically you had your "Wiki" and "100" (score) button already, but they just were behind your Option buttons so you could barely see them.
    #design.kv    
    
    <HomeScreen>:
        BoxLayout:
            GridLayout:
                cols: 1
    
            GridLayout:
                cols: 2
    
                Button:
                    id: infoButton
                    text: "Wiki"
    
                Label:
                    id: score
    
            GridLayout:
                cols: 1
    
                Label:
                    id: Question
                    text: "Question"
    
                Button:
                    id: Button1
                    text: "Option 1"
    
                Button:
                    id: Button1
                    text: "Option 2"
    
                Button:
                    id: Button1
                    text: "Option 3"
    
                Button:
                    id: Button1
                    text: "Option 4"
    
    <RootWidget>:
        HomeScreen:
            name: "home_screen"