如何在Kivy中为倒数计时器创建一圈功能

时间:2019-06-22 23:54:58

标签: python timer kivy kivy-language

我有一个倒计时计时器,该计时器从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循环实际上是在应用程序真正启动之前从零迭代到一个,因此,在倒计时开始时,i已经等于1(而不是先从a到零运行,且i = 0且然后从新的a变为零(i = 1)。我想这是因为for循环在错误的位置(即不是在调用start函数时),但是我一直无法找出解决方法。 这也是我第一次使用堆栈溢出,所以如果您需要了解其他信息,请告诉我。

2 个答案:

答案 0 :(得分:0)

很难理解您的代码,但这是您的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'

这是一个非常简单的方法。我确信startsecondAnim方法可以结合为一种逻辑更多的方法。

答案 1 :(得分:0)

以下是将倒数计时重复指定次数的版本:

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