Reputation: 47
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
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