I'm semi-OK with Python but brand new to Kivy, I know my problem is referencing the label ID but I can't seem to solve it and searching doesn't seem to give me what I need.
I'm trying to get a label to display the current time, so I know I have the right framework in terms of updating etc but I'm sure its all down to referencing the label ID somehow and its that I'm struggling with?
The following code runs fine, displays the labels etc until I try to update the label_text.text
at which point i get an error: AttributeError: 'float' object has no attribute 'lbl_time'
. I've tried str(time.strftime("%H:%M:%S"))
but that doesn't solve it.
from kivy.app import App
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.properties import ListProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.uix.screenmanager import ScreenManager, Screen, WipeTransition, FadeTransition
from kivy.uix.anchorlayout import AnchorLayout
from kivy.properties import ObjectProperty, StringProperty
from kivy.clock import Clock
import time
from datetime import datetime
class MainScreen(Screen):
def update_time(self):
lbl_time = ObjectProperty()
MyTime = time.strftime("%H:%M:%S")
self.lbl_time.text = MyTime
class DetailScreen(Screen):
pass
class SettingsScreen(Screen):
pass
class MyScreenManager(ScreenManager):
pass
root_widget = Builder.load_string('''
MyScreenManager:
MainScreen:
DetailScreen:
SettingsScreen:
<MainScreen>:
name: 'main'
BoxLayout:
orientation: 'vertical'
Label:
id: lbl_time
text: 'Time'
font_size: 60
Label:
text: 'Main2'
font_size: 30
GridLayout:
cols: 2
Label:
text: 'Bottom'
font_size: 30
Label:
text: 'Bottom1'
font_size: 30
<DetailScreen>:
name: 'details'
<SettingsScreen>:
name: 'settings'
''')
class ScreenManagerApp(App):
def build(self):
return root_widget
def on_start(self):
Clock.schedule_interval(MainScreen.update_time, 1)
ScreenManagerApp().run()
This was more of a Python problem rather than a Kivy one. You were calling the update_time
of the class MainScreen
class, not of the object/instance of the MainScreen
. Basically, you would need to save a reference to the object (self.main_screen) in the build
method, and then use it in the on_start.
class ScreenManagerApp(App):
def build(self):
self.main_screen = MainScreen()
return self.main_screen
def on_start(self):
Clock.schedule_interval(self.main_screen.update_time, 1)
Also you cannot access id outside of the kv language, i.e. in the python. You have to reference the id by adding a property, e.g. the_time
:
<MainScreen>:
name: 'main'
the_time: _id_lbl_time
BoxLayout:
orientation: 'vertical'
Label:
id: _id_lbl_time
A minor problem is that the update_time()
receives to parameters. Also, there were quite a few weird things in your code, so I couldn't run the code. I fixed all the above in the code below:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
from kivy.properties import ObjectProperty, StringProperty
from kivy.clock import Clock
import time
from datetime import datetime
Builder.load_string('''
<MainScreen>:
name: 'main'
the_time: _id_lbl_time
BoxLayout:
orientation: 'vertical'
Label:
id: _id_lbl_time
text: 'Time'
font_size: 60
''')
class MainScreen(Screen):
def update_time(self, sec):
MyTime = time.strftime("%H:%M:%S")
self.the_time.text = MyTime
class ScreenManagerApp(App):
def build(self):
self.main_screen = MainScreen()
return self.main_screen
def on_start(self):
Clock.schedule_interval(self.main_screen.update_time, 1)
ScreenManagerApp().run()