fastmhc
fastmhc

Reputation: 47

update a kivy label text in another class

This is a follow up to a previous question I've asked on how to change the properties of a kivy widget (update a kivy label text in another class). I've been trying to figure out why the temperature reading on the Menuscreen updates but within the Mashscreen, the text doesn't update. It looks like the values are being passed to eh temperature1def method but the screen widget doesn't update.

Also, is it better to send the value using

Mashscreen().temperature1def(self.test_temp)

or is it better practice to use

self.stuff_p.text = str(self.test_temp) + u'\u00B0F'

within the MenuScreen to update the label within the Mashscreen? Thanks in advance.

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
from kivy.properties import ObjectProperty
from kivy.clock import Clock

sm = """


ScreenManager:
    #Handling the gesture event.
    id:manager
    canvas.before:
        Color:
            rgba: 0.5, 0.5, 0.5, 0.5
        Rectangle:
            pos: 0,0
            size: 800, 480
    MenuScreen:
        id:MenuScreen
        name:'MenuScreen'
        manager: manager
    Mashscreen:
        id:Mashscreen
        name: 'Mashscreen'
        manager: manager



<MenuScreen>:
    stuff_r: mainel1temp
    Button:
        text: "Go to mashscreen"
        on_release:
            root.manager.current = "Mashscreen"

    Label:
        id: mainel1temp
        text:'0'
        size_hint: None, None
        size: 75,50
        pos: 295,308
        font_size:'22sp'
        text_size: self.size
        halign: 'left'
        valign: 'middle'


<Mashscreen>:
    stuff_p: temperature1
    FloatLayout:


        Label:
            id: temperature1
            text:'100'
            size_hint: None, None
            size: 75,50
            pos: 50,275
            font_size:'22sp'
            text_size: self.size
            halign: 'left'
            valign: 'middle'


"""

class MenuScreen(Screen):
    test_temp = 99
    stuff_r = ObjectProperty(None)

    def __init__(self,**kwargs):
        super(MenuScreen,self).__init__(**kwargs)
        Clock.schedule_interval((self.read_temp), 1)
        #self.read_temp(1)

    def read_temp(self, dt):

        self.test_temp += 1
        self.stuff_r.text = str(self.test_temp) + u'\u00B0F'
        Mashscreen().temperature1def(self.test_temp)
        #self.parent.ids.Mashscreen.stuff_p.text = str(self.test_temp) + u'\u00B0F'




class Mashscreen(Screen):
    stuff_p = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(Mashscreen, self).__init__(**kwargs)

    def temperature1def(self, temp1):
        print(temp1)
        self.stuff_p.text = str(temp1)

class TestApp(App):

    def build(self):

        return Builder.load_string(sm)

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

Upvotes: 2

Views: 1893

Answers (1)

Tshirtman
Tshirtman

Reputation: 5947

First…

    Mashscreen().temperature1def(self.test_temp)

This doesn't call the temperature1def method on your Mashscreen instance in the UI, instead, it creates a new Mashscreen instance, calls the method on it, and then let this object be garbage collected by python. If you want to update your UI, you need to get a reference to the widget you want to update.

You define your Mashscreen in the root rule of your application, so you can get it by its id in this object.

App.get_running_app() will return a reference to your currently running app, which has a root attribute, which is your root widget, any widget at the root of a rule can use its ids attribute to get a reference to any id defined in its scope, so.

App.get_running_app().root.ids.Mashscreen.temperature1def(self.test_temp)

will certainly be more like what you actually want to do.

Now, regarding the question about how to do it best in python kivy, i find that it's cleaner to do something like.

App.get_running_app().root.ids.Mashscreen.temperature = self.test_temp

and then to change your Mashscreen class to have a temperature NumericProperty, and to change your kv rule to use this value in the Label.

<Mashscreen>:
    stuff_p: temperature1
    FloatLayout:
        Label:
            id: temperature1
            text: '%s' % root.temperature
            size_hint: None, None
            size: 75,50
            pos: 50,275
            font_size:'22sp'
            text_size: self.size
            halign: 'left'
            valign: 'middle'

Upvotes: 2

Related Questions