Как создать функцию круга для таймера обратного отсчета в Киви - PullRequest
0 голосов
/ 23 июня 2019

У меня есть таймер обратного отсчета, который начинается со случайного целого числа в диапазоне, заданном аргументами 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))

Приложение работает так, как ожидается для первого обратного отсчета.Случайное число выбирается и таймер начинает обратный отсчет до нуля, но он останавливается и отображает «ЗАВЕРШЕНО» после первого обратного отсчета.Кажется, что цикл for итерирует от нуля до единицы, прежде чем приложение действительно запустится, поэтому к моменту начала обратного отсчета я уже равен 1 (вместо запуска сначала с a до нуля с i = 0 изатем из нового а в ноль с i = 1).Я предполагаю, что это потому, что цикл for находится не в том месте (т.е. не при вызове функции start), но я не смог решить, как это исправить.Я также впервые использую переполнение стека, поэтому, пожалуйста, дайте мне знать, если вам нужно знать что-то еще.

Ответы [ 2 ]

0 голосов
/ 25 июня 2019

Вот версия, которая повторяет обратный отсчет указанное количество раз:

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()
0 голосов
/ 23 июня 2019

Трудно понять ваш код, но вот версия вашего 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 можно объединить как один метод с немного большей логикой.

...