如何在 Kivy 中为倒数计时器创建圈功能
How to create a lap function for a countdown timer in Kivy
我有一个倒数计时器,它从 randint() 参数给定范围内的随机整数开始,倒数到零。目的是使计时器在第一次达到零时以新的随机数重新启动(即圈功能)并在第二次达到零时显示 "FINISH"。
这是我第一次使用 kivy,如果解决方案很明显,我们深表歉意。目前我只需要两次迭代,但我可能需要稍后进行调整,以便计时器在最终停止之前可以循环任意次数。圈数将在 运行 应用程序之前在代码中确定,而不是由应用程序用户在 运行 应用程序时确定。
from kivy.app import App
from kivy.uix.label import Label
from kivy.animation import Animation
from kivy.properties import NumericProperty
from random import randint
class IncrediblyCrudeClock(Label):
for i in range(2):
r=randint(3,7)
a = NumericProperty(r) # Number of seconds to countdown
def start(self): #Function to initiate the countdown
Animation.cancel_all(self) # stop any current animations
self.anim = Animation(a=0, duration=self.a) #a=0 sets the
#final destination of a. duration sets the time taken to reach stopping
#point (i.e 5 seconds for a=5)
def finish_callback(animation, incr_crude_clock):
if self.i==1:
incr_crude_clock.text = "FINISHED" #when the clock
#reaches zero, display "FINISHED"
self.anim.bind(on_complete=finish_callback) #call the
#finish_callback function once a=0
self.anim.start(self) #Start the animation (otherwise clock
#stuck at 5 for a=5)
class TimeApp(App):
def build(self):
crudeclock = IncrediblyCrudeClock()
crudeclock.start()
return crudeclock
if __name__ == "__main__":
TimeApp().run()
<IncrediblyCrudeClock>
text: str(round(self.a, 1))
该应用按预期 运行 第一次倒计时。选择一个随机数,计时器倒计时到零,但在第一次倒计时后停止并显示 "FINISHED"。似乎 for 循环在应用程序实际启动之前从 0 迭代到 1,因此,在倒计时开始时,i 已经等于 1(而不是 运行ning 首先从 a 到 0 i=0,然后从新的 a 到零,i=1)。我想这是因为 for 循环在错误的位置(即不是在调用 start 函数时),但我一直无法弄清楚如何纠正这个问题。
这也是我第一次使用stack overflow,所以如果你需要知道任何其他的,请告诉我。
很难理解您的代码,但这里是您的 IncrediblyCrudeClock
版本:
class IncrediblyCrudeClock(Label):
a = NumericProperty(0) # Number of seconds to countdown
def start(self):
self.a = randint(3, 7)
self.anim = Animation(a=0, duration=self.a)
self.anim.bind(on_complete=self.secondAnim)
print('starting first anim')
self.anim.start(self)
def secondAnim(self, animation, incr_crude_clock):
self.a = randint(3, 7)
self.anim = Animation(a=0, duration=self.a)
self.anim.bind(on_complete=self.finish_callback)
print('starting second anim')
self.anim.start(self)
def finish_callback(self, animation, incr_crude_clock):
print('in finish_callback')
self.text = 'FINISHED'
这是一个非常简单的方法。我确信 start
和 secondAnim
方法可以组合为一种方法,具有更多逻辑。
这是一个重复倒计时指定次数的版本:
from random import randint
from kivy.animation import Animation
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import NumericProperty
from kivy.uix.label import Label
class IncrediblyCrudeClock(Label):
a = NumericProperty(0) # Number of seconds to countdown
def __init__(self, **kwargs):
self.max_laps = kwargs.pop('laps', 2) # default is to do 2 laps
self.lap_counter = 0
super(IncrediblyCrudeClock, self).__init__(**kwargs)
def start(self, *args):
self.lap_counter += 1
self.a = randint(3, 7)
self.anim = Animation(a=0, duration=self.a)
if self.lap_counter >= self.max_laps:
# this is the last lap, set on_complete to call self.finish_callback
self.anim.bind(on_complete=self.finish_callback)
else:
# not finished yet, call self.start again
self.anim.bind(on_complete=self.start)
print('starting anim number', self.lap_counter)
self.anim.start(self)
def finish_callback(self, animation, incr_crude_clock):
print('in finish_callback')
self.text = 'FINISHED'
Builder.load_string('''
<IncrediblyCrudeClock>
text: str(round(self.a, 1))
''')
class TimeApp(App):
def build(self):
# specify the number of repetitions in the constructor
crudeclock = IncrediblyCrudeClock(laps=3)
crudeclock.start()
return crudeclock
if __name__ == "__main__":
TimeApp().run()
我有一个倒数计时器,它从 randint() 参数给定范围内的随机整数开始,倒数到零。目的是使计时器在第一次达到零时以新的随机数重新启动(即圈功能)并在第二次达到零时显示 "FINISH"。
这是我第一次使用 kivy,如果解决方案很明显,我们深表歉意。目前我只需要两次迭代,但我可能需要稍后进行调整,以便计时器在最终停止之前可以循环任意次数。圈数将在 运行 应用程序之前在代码中确定,而不是由应用程序用户在 运行 应用程序时确定。
from kivy.app import App
from kivy.uix.label import Label
from kivy.animation import Animation
from kivy.properties import NumericProperty
from random import randint
class IncrediblyCrudeClock(Label):
for i in range(2):
r=randint(3,7)
a = NumericProperty(r) # Number of seconds to countdown
def start(self): #Function to initiate the countdown
Animation.cancel_all(self) # stop any current animations
self.anim = Animation(a=0, duration=self.a) #a=0 sets the
#final destination of a. duration sets the time taken to reach stopping
#point (i.e 5 seconds for a=5)
def finish_callback(animation, incr_crude_clock):
if self.i==1:
incr_crude_clock.text = "FINISHED" #when the clock
#reaches zero, display "FINISHED"
self.anim.bind(on_complete=finish_callback) #call the
#finish_callback function once a=0
self.anim.start(self) #Start the animation (otherwise clock
#stuck at 5 for a=5)
class TimeApp(App):
def build(self):
crudeclock = IncrediblyCrudeClock()
crudeclock.start()
return crudeclock
if __name__ == "__main__":
TimeApp().run()
<IncrediblyCrudeClock>
text: str(round(self.a, 1))
该应用按预期 运行 第一次倒计时。选择一个随机数,计时器倒计时到零,但在第一次倒计时后停止并显示 "FINISHED"。似乎 for 循环在应用程序实际启动之前从 0 迭代到 1,因此,在倒计时开始时,i 已经等于 1(而不是 运行ning 首先从 a 到 0 i=0,然后从新的 a 到零,i=1)。我想这是因为 for 循环在错误的位置(即不是在调用 start 函数时),但我一直无法弄清楚如何纠正这个问题。 这也是我第一次使用stack overflow,所以如果你需要知道任何其他的,请告诉我。
很难理解您的代码,但这里是您的 IncrediblyCrudeClock
版本:
class IncrediblyCrudeClock(Label):
a = NumericProperty(0) # Number of seconds to countdown
def start(self):
self.a = randint(3, 7)
self.anim = Animation(a=0, duration=self.a)
self.anim.bind(on_complete=self.secondAnim)
print('starting first anim')
self.anim.start(self)
def secondAnim(self, animation, incr_crude_clock):
self.a = randint(3, 7)
self.anim = Animation(a=0, duration=self.a)
self.anim.bind(on_complete=self.finish_callback)
print('starting second anim')
self.anim.start(self)
def finish_callback(self, animation, incr_crude_clock):
print('in finish_callback')
self.text = 'FINISHED'
这是一个非常简单的方法。我确信 start
和 secondAnim
方法可以组合为一种方法,具有更多逻辑。
这是一个重复倒计时指定次数的版本:
from random import randint
from kivy.animation import Animation
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import NumericProperty
from kivy.uix.label import Label
class IncrediblyCrudeClock(Label):
a = NumericProperty(0) # Number of seconds to countdown
def __init__(self, **kwargs):
self.max_laps = kwargs.pop('laps', 2) # default is to do 2 laps
self.lap_counter = 0
super(IncrediblyCrudeClock, self).__init__(**kwargs)
def start(self, *args):
self.lap_counter += 1
self.a = randint(3, 7)
self.anim = Animation(a=0, duration=self.a)
if self.lap_counter >= self.max_laps:
# this is the last lap, set on_complete to call self.finish_callback
self.anim.bind(on_complete=self.finish_callback)
else:
# not finished yet, call self.start again
self.anim.bind(on_complete=self.start)
print('starting anim number', self.lap_counter)
self.anim.start(self)
def finish_callback(self, animation, incr_crude_clock):
print('in finish_callback')
self.text = 'FINISHED'
Builder.load_string('''
<IncrediblyCrudeClock>
text: str(round(self.a, 1))
''')
class TimeApp(App):
def build(self):
# specify the number of repetitions in the constructor
crudeclock = IncrediblyCrudeClock(laps=3)
crudeclock.start()
return crudeclock
if __name__ == "__main__":
TimeApp().run()