I'm developing a multiple page Kivy app that I want to have a clock widget in several pages. I was able to implement it on every page as an individual instance but i wanted to change it to a reusable widget but it's not updating during the intervals
This is the .kv file implementation
ScreenManager:
id: screen_manager
HomeScreen:
id: home_screen
name: 'home_screen'
manager: 'screen_manager'
<ClockWidget>:
Label:
text_size: self.size
halign: 'left'
valign: 'middle'
id: clocktime
text: root.ClockTimeDisplay
<HomeScreen>:
orientation: 'vertical'
ScrollView:
do_scroll_x: True
scroll_distance: 20
BoxLayout:
orientation: 'vertical'
ClockWidget:
here is the .py file. Within the update_clock function I've tried all 3 of these implementations at one time or another. It prints the time properly but doesn't update the label, stays saying "dummy text".
class ClockWidget(Label):
ClockTimeDisplay = StringProperty()
ClockTimeDisplay = "dummy text"
text = ClockTimeDisplay
def __init__(self, **kwargs):
super(ClockWidget, self).__init__(**kwargs)
def update_clock(self, *args):
print(self.text)
#I've tried all 3 of these implimentations at one time or another.
self.ClockTimeDisplay = str(datetime.now().strftime('%H:%M:%S'))
self.text = str(datetime.now().strftime('%H:%M:%S'))
self.ids.clocktime.text = str(datetime.now().strftime('%H:%M:%S'))
return ClockTimeDisplay
class HomeScreen(Screen):
pass
class regatta_racer(App):
def build(self):
clock_widget = ClockWidget()
Clock.schedule_interval(clock_widget.update_clock, .1)
return Builder.load_file('regatta_racer.kv')
if __name__ == "__main__":
regatta_racer().run()
I've also tried triggering the interval within a on_load function inside the ClockWidget but that didn't work either.
Any help would be greatly appreciated.
The problem is that the ClockWidget created in the build method is different from the ClockWidget created as a child of BoxLayout in the .kv, in your case only the Clock only calls the update_clock method of the first.
On the other hand I see it unnecessary to create a new StringProperty in ClockWidget since it is a Label and has the property "text", and another strange thing is that a Label has another Label as a child.
Considering the above, the solution is:
from datetime import datetime
from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
from kivy.uix.label import Label
class ClockWidget(Label):
def __init__(self, **kwargs):
super().__init__(**kwargs)
Clock.schedule_interval(self.update_clock, 0.1)
def update_clock(self, *args):
self.text = datetime.now().strftime("%H:%M:%S")
class HomeScreen(Screen):
pass
class regatta_racer(App):
def build(self):
return Builder.load_file("regatta_racer.kv")
if __name__ == "__main__":
regatta_racer().run()
ScreenManager:
id: screen_manager
HomeScreen:
id: home_screen
name: 'home_screen'
manager: 'screen_manager'
<ClockWidget>:
text_size: self.size
halign: 'left'
valign: 'middle'
<HomeScreen>:
orientation: 'vertical'
ScrollView:
do_scroll_x: True
scroll_distance: 20
BoxLayout:
orientation: 'vertical'
ClockWidget: