Reputation: 47
I'm having difficulty figuring out how to change the text of a label within a kivy widget. For simplicity, I have a label set to 0 and I would like to change the text to read 30 in this example. However, I get the following error.
AttributeError: 'super' object has no attribute 'getattr'
I understand that I'm probably not properly targeting that widget and I am hoping someone can please explain how to specifically reference the text of this label (self.ids.mainel1temp.stuff_r.text = '30') to update (with more detail than fixing the code)
#!/usr/bin/kivy
import kivy
from random import random
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.switch import Switch
from kivy.uix.label import Label
from kivy.config import Config
Config.set('graphics', 'width', '800')
Config.set('graphics', 'height', '480')
Builder.load_string("""
<Menuscreen>:
#Handling the gesture event.
ScreenManager:
id: manager
Screen:
id: main_screen
name:'main_screen'
stuff_r: mainel1temp
FloatLayout:
Label:
id: mainel1temp
size: self.texture_size
text:'0'
size_hint: None, None
text_size: 75,75
pos: 295,308
font_size:'20sp'
halign: 'center'
""")
class Thermostuff(Screen):
stuff_r = ObjectProperty(None)
def starttherm(self):
Clock.schedule_interval((self.read_temp), 1)
def read_temp(self, dt):
self.ids.mainel1temp.stuff_r.text = '30'
Thermrun = Thermostuff()
Thermrun.starttherm()
class MenuScreen(Screen):
pass
sm = ScreenManager()
menu_screen = MenuScreen(name='menu')
sm.add_widget(menu_screen)
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
Upvotes: 1
Views: 1224
Reputation: 5405
You do a couple of things wrong here.
You dont want to put a ScreenManager
inside a Screen
Only one ScreenManager
is needed.
Then you can start the Clock
in the __init__
of the Thermostuff(Screen)
Or if you want it to initiate on_enter
you need to overrite that. In that case you might want to check somehow, if its allready started, so you wont have multiple clocks running.
Then when you create an ObjectProperty
you dont need self.ids
, because you allready created that property. So self.stuff_r
is now the label.
I rewrote your example a bit, to demonstrate this.
Try this:
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 = """
#Handling the gesture event.
ScreenManager:
id: manager
MenuScreen:
Button:
text: "Go to Thermostuff"
on_release:
root.current = "main_screen"
Thermostuff:
name:'main_screen'
stuff_r: mainel1temp
FloatLayout:
Label:
id: mainel1temp
size: self.texture_size
text:'0'
size_hint: None, None
text_size: 75,75
pos: 295,308
font_size:'20sp'
halign: 'center'
"""
class Thermostuff(Screen):
stuff_r = ObjectProperty(None)
test_temp = 0
def __init__(self,**kwargs):
super(Thermostuff,self).__init__(**kwargs)
Clock.schedule_interval((self.read_temp), 1)
def read_temp(self, dt):
self.test_temp += 1
self.stuff_r.text = str(self.test_temp)
class MenuScreen(Screen):
pass
class TestApp(App):
def build(self):
return Builder.load_string(sm)
if __name__ == '__main__':
TestApp().run()
Upvotes: 1