I’m making a stopwatch using Kivy that includes “Minutes, seconds, milliseconds”.
But the problem is that the Clock method doesn’t seem to support the shorter time below 0.02. So no matter what numbers you give, it still can not catch up with the milliseconds’ change and counting time slower than the real-time (You can see it clearly in my code below).
So is there any better way to update my Kivy’s GUI by milliseconds, so I can display the numbers on my app’s screen?
Here’s the code I extracted from my main source:
from kivy.uix.relativelayout import RelativeLayout from kivy.lang import Builder from kivy.clock import Clock from functools import partial Builder.load_string(""" <ModifyTime>: id: name BoxLayout: id: time spacing: 1 size_hint_y: None height: minute.height TextInput: id: minute hint_text: "Minutes" size_hint: None,None width: time_scale.texture_size[0] + dp(14) height: time_scale.texture_size[1] + dp(12) multiline: False TextInput: id: second hint_text: "Seconds" size_hint: None,None width: time_scale.texture_size[0] + dp(14) height: time_scale.texture_size[1] + dp(12) multiline: False TextInput: id:milisecond hint_text: "Miliseconds" size_hint: None,None width: time_scale.texture_size[0] + dp(14) height: time_scale.texture_size[1] + dp(12) multiline: False Button: text: "Activate stopwatch" on_release: root.activate_stopwatch(root) Label: id: time_scale opacity: 0 text: "00:00:00" size_hint: None,None size: 0,0 """) class ModifyTime(RelativeLayout): def __init__(self,**kwargs): super().__init__(**kwargs) def activate_stopwatch(self,watch): watch.ids.minute.text="0" watch.ids.second.text="0" watch.ids.milisecond.text="0" self.stopwatch=Clock.schedule_interval(partial(self._time_update,watch),0.001) def _time_update(self,watch,dt): watch.ids.milisecond.text=str(int(watch.ids.milisecond.text)+1) self._time_update_calculate(watch) def _time_update_calculate(self,watch): if watch.ids.milisecond.text == "1000": watch.ids.milisecond.text = "0" watch.ids.second.text=str(int(watch.ids.second.text)+1) if watch.ids.second.text == "60": watch.ids.second.text == "0" watch.ids.minute.text=str(int(watch.ids.minute.text)+1) if __name__ == "__main__": from kivy.app import App class TestApp(App): def build(self): return ModifyTime() TestApp().run()
Advertisement
Answer
I modified your .py
code to the following which should fairly count upto milliseconds (should work without any changes in config).
class ModifyTime(RelativeLayout): def __init__(self,**kwargs): super().__init__(**kwargs) self.milisec = 0 def activate_stopwatch(self,watch): watch.ids.minute.text="0" watch.ids.second.text="0" watch.ids.milisecond.text="0" self.stopwatch=Clock.schedule_interval(partial(self._time_update,watch),0.001) def _time_update(self,watch,dt): self.milisec += 1000*dt sec, mili = divmod(self.milisec, 1000) mint, sec = divmod(sec, 60) watch.ids.milisecond.text = str(int(mili)) watch.ids.second.text = str(int(sec)) watch.ids.minute.text = str(int(mint)) if __name__ == "__main__": from kivy.app import App class TestApp(App): def build(self): return ModifyTime() TestApp().run()