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()
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()