Как перезапустить анимацию Kivy

#python #kivy

#python #kivy

Вопрос:

Я пытаюсь создать простой таймер обратного отсчета, я хочу иметь возможность перезапустить его одним нажатием кнопки, прямо сейчас он не запустится, я просто не могу сделать это правильно. Чего мне здесь не хватает?

KV

 <RootWidget>:
    #:import randint  random.randint
    orientation: "vertical"
    CountDownLbl:
        id: anim_label
        text: "{0:.3f}".format(float(self.startCount - self.angle / 360))
        font_size: 30
        canvas:
            Color:
                rgb: 0,1,0
            Line:
                circle:self.center_x, self.center_y, 90, 0, self.angle % 360
                width: 30
    Button:
        size_hint_y: 0.1
        text: "Start"
        on_press: anim_label.start()
 

и код

 COUNT=1

class RootWidget(FloatLayout):
    pass

class CountDownLbl(Label):
    startCount = COUNT
    angle = NumericProperty(0)

    def __init__(self, **kwargs):
        super(CountDownLbl, self).__init__(**kwargs)

    def start(self):
        self.startCount = COUNT
        self.anim = Animation(angle=360 * self.startCount,  duration=self.startCount)
        self.in_progress = True
        self.anim.start(self)

class TestApp(App):
    def build(self):
        return RootWidget()

if __name__ == '__main__':
    TestApp().run()
 

Ответ №1:

Проблема в том, что первая анимация анимирует angle свойство 360 , а последующие анимации пытаются анимировать angle свойство 360 снова, что не приводит к фактической анимации. Исправление заключается в увеличении вашей COUNT анимации после каждой анимации, например:

 def start(self):
    global COUNT
    self.startCount = COUNT
    self.anim = Animation(angle=360 * self.startCount,  duration=self.startCount)
    self.in_progress = True
    self.anim.start(self)
    COUNT  = 1
 

Ответ №2:

Отвечая на мой собственный вопрос, хвала Джону.

Спасибо Джону Андерсону. Это окончательная версия. Самое главное, я обновляю текст в функции вместо того, чтобы делать это в KV, а во-вторых, приращение должно быть по значению ТАЙМЕРА, а не на 1. Последний пример можно найти здесь https://github.com/vmindru/amb_pit_timer/blob/main/simple_timer.py

код

 TIMER_DURATION = 5

class CountDownLbl(Label):
    angle = NumericProperty(0)
    timer_duration = NumericProperty(0)

    def __init__(self, **kwargs):
        super(CountDownLbl, self).__init__(**kwargs)
        self.anim_duration = self.timer_duration
        self.in_progress = False

    def start(self):
        if not self.in_progress:
            self.anim = Animation(angle=360 * self.anim_duration,  duration=self.timer_duration)
            self.in_progress = True
            self.anim.bind(on_complete=self.finish, on_progress=self.update_timer)
            self.anim.start(self)
            self.anim_duration  = TIMER_DURATION

    def finish(self, animation, widget):
        widget.text = "FINISHED"
        self.in_progress = False

    def update_timer(self, animation, widget, progression):
        text = ((self.timer_duration * 60000)*(1-progression))/60000
        widget.text = "{0:.3f}".format(float(text))
 

kv

 CountDownLbl:
    id: anim_label
    timer_duration: 5                 
    font_size: 30           
    text: "{}.000".format(self.timer_duration)
    canvas:
        Color:                                                                                                     
            rgb: 0,1,0                                                                                             
        Line:                                  
            circle:self.center_x, self.center_y, 90, 0, self.angle % 360
            width: 30