Wednesday, February 2, 2022

[SOLVED] Kivy Python IDs problems

Issue

I was using my main class as widget and was passing IDs from kv file to python without problems. Now changed it to a screen as I need to switch between 2 screens but now I cant access the IDs declared in kv file. I get error - 'MainScreen'object has no attribute 'labINFO' - (this is the first label id I am trying to modify.) Here are parts of py and kv files

    from kivy.app import App
    from kivy.uix.floatlayout import FloatLayout
    from kivy.uix.gridlayout import GridLayout
    from kivy.uix.label import Label
    from kivy.uix.button import Button
    from kivy.uix.textinput import TextInput
    from kivy.uix.widget import Widget
    from kivy.properties import ObjectProperty
    from kivy.core.window import Window
    from kivy.uix.popup import Popup
    from kivy.uix.screenmanager import ScreenManager, Screen
    from kivy.clock import Clock
    
    class GSMNosScreen(Screen):
    
        def gsmclose(self, obj):
            Clock.schedule(self.startgetTemps,dataInterval)
            BoilerApp.sm.current = 'main'        
    
    class MainScreen(Screen):
    
       ....
       ....
    
       def __init__(self, **kwargs):
            super(MainScreen, self).__init__(**kwargs)
            
            self.labINFO.text = "Waiting for Pic..."
            self.labM1.text = str(b1Min)
            self.labM2.text = str(b2Min)

sm = ScreenManager() #transition=NoTransition()
sm.add_widget(MainScreen(name='main'))
sm.add_widget(GSMNosScreen(name='gsmnos'))


class BoilerApp(App):

    def build(self):
        self.title = 'Boiler Monitor'
        return sm

if __name__ == "__main__":
    from kivy.core.window import Window
    Window.fullscreen = True
    app = BoilerApp()
    app.run()

KV file

<GSMNosScreen>:
    labN1: labN1
    
    size_hint: .5, .5
    auto_dismiss: False

    title: "GSM Numbers"                 # <<<<<<<<
    separator_height: 0       # <<<<<<<<
    GridLayout:
        cols: 1
        size: root.width, root.height
        MyTLab:
            id:labN1
            font_size: 20
            text: "Number 1 : ..."
        MyBut:
            text: "Close"
            font_size: 20
            size_hint: .2, .2
            on_press: gsmclose()



<MainScreen>

    labM1: labM1
    labM2: labM2
    labM3: labM3
    labM4: labM4
    labM5: labM5

    labINFO: labINFO
    labDT:   labDT
    
    GridLayout:
        cols: 1
        size: root.width, root.height
        MyTLab:
            text: "Monitor"
            underline: True
            size_hint: .5, .2
        BoxLayout:
            orientation: "horizontal"
            size_hint_y: .2
            MySTLab:
                color: 0.8,.2,.2,0.7
                text: "Min °C"
                size_hint_x: 1.5
                font_size: 25
            MyMLab:
                id: labM1
                text: "50"
            MyMLab:
                id: labM2
                text: "50"
            MyMLab:
                id: labM3
                text: "50"
            MyMLab:
                id: labM4
                text: "50"
        BoxLayout:
            orientation: "horizontal"
            #cols:2
            size_hint_y: .1
            Label:
                id: labDT
                color: 0,1,0.5,0.8
                text: "Starting ...."
                font_size: sp(20)
                size_hint_x: .3
            Label:
                id: labINFO
                color: 0,1,0.5,0.8
                text: "...."
                font_size: sp(20)
                size_hint_x: .7

Solution

I believe the problem is that the kv file has not been loaded yet when the lines:

sm = ScreenManager() #transition=NoTransition()
sm.add_widget(MainScreen(name='main'))
sm.add_widget(GSMNosScreen(name='gsmnos'))

are executed.

Try moving the above lines into the build() method of the App:

class BoilerApp(App):

    def build(self):
        self.title = 'Boiler Monitor'
        sm = ScreenManager()  # transition=NoTransition()
        sm.add_widget(MainScreen(name='main'))
        sm.add_widget(GSMNosScreen(name='gsmnos'))
        return sm

The kv file (if it is named boiler.kv) is loaded before the build() mehod is called.



Answered By - John Anderson
Answer Checked By - Marilyn (WPSolving Volunteer)