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:
JavaScript
x
97
97
1
from kivy.uix.relativelayout import RelativeLayout
2
3
from kivy.lang import Builder
4
5
from kivy.clock import Clock
6
7
from functools import partial
8
9
Builder.load_string("""
10
<ModifyTime>:
11
id: name
12
13
BoxLayout:
14
id: time
15
16
spacing: 1
17
18
size_hint_y: None
19
height: minute.height
20
21
TextInput:
22
id: minute
23
hint_text: "Minutes"
24
25
size_hint: None,None
26
width: time_scale.texture_size[0] + dp(14)
27
height: time_scale.texture_size[1] + dp(12)
28
29
multiline: False
30
31
TextInput:
32
id: second
33
hint_text: "Seconds"
34
35
size_hint: None,None
36
width: time_scale.texture_size[0] + dp(14)
37
height: time_scale.texture_size[1] + dp(12)
38
39
multiline: False
40
41
TextInput:
42
id:milisecond
43
hint_text: "Miliseconds"
44
45
size_hint: None,None
46
width: time_scale.texture_size[0] + dp(14)
47
height: time_scale.texture_size[1] + dp(12)
48
49
multiline: False
50
51
Button:
52
text: "Activate stopwatch"
53
on_release:
54
root.activate_stopwatch(root)
55
56
Label:
57
id: time_scale
58
opacity: 0
59
text: "00:00:00"
60
61
size_hint: None,None
62
size: 0,0
63
64
""")
65
66
class ModifyTime(RelativeLayout):
67
def __init__(self,**kwargs):
68
super().__init__(**kwargs)
69
70
def activate_stopwatch(self,watch):
71
watch.ids.minute.text="0"
72
watch.ids.second.text="0"
73
watch.ids.milisecond.text="0"
74
self.stopwatch=Clock.schedule_interval(partial(self._time_update,watch),0.001)
75
76
def _time_update(self,watch,dt):
77
watch.ids.milisecond.text=str(int(watch.ids.milisecond.text)+1)
78
79
self._time_update_calculate(watch)
80
81
def _time_update_calculate(self,watch):
82
if watch.ids.milisecond.text == "1000":
83
watch.ids.milisecond.text = "0"
84
watch.ids.second.text=str(int(watch.ids.second.text)+1)
85
if watch.ids.second.text == "60":
86
watch.ids.second.text == "0"
87
watch.ids.minute.text=str(int(watch.ids.minute.text)+1)
88
89
if __name__ == "__main__":
90
from kivy.app import App
91
92
class TestApp(App):
93
def build(self):
94
return ModifyTime()
95
96
TestApp().run()
97
Advertisement
Answer
I modified your .py
code to the following which should fairly count upto milliseconds (should work without any changes in config).
JavaScript
1
31
31
1
class ModifyTime(RelativeLayout):
2
def __init__(self,**kwargs):
3
super().__init__(**kwargs)
4
self.milisec = 0
5
6
def activate_stopwatch(self,watch):
7
watch.ids.minute.text="0"
8
watch.ids.second.text="0"
9
watch.ids.milisecond.text="0"
10
self.stopwatch=Clock.schedule_interval(partial(self._time_update,watch),0.001)
11
12
def _time_update(self,watch,dt):
13
self.milisec += 1000*dt
14
sec, mili = divmod(self.milisec, 1000)
15
mint, sec = divmod(sec, 60)
16
17
watch.ids.milisecond.text = str(int(mili))
18
watch.ids.second.text = str(int(sec))
19
watch.ids.minute.text = str(int(mint))
20
21
22
if __name__ == "__main__":
23
from kivy.app import App
24
25
class TestApp(App):
26
def build(self):
27
return ModifyTime()
28
29
TestApp().run()
30
31