Veaceslav Mindru
Veaceslav Mindru

Reputation: 97

How to restart Kivy Animation

I am trying to create a simple countdown timer, i want to be able to restart it on the Button click, right now it won't start other, i just can not get it right. What am i missing here?

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

and the code

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

Upvotes: 0

Views: 102

Answers (2)

Veaceslav Mindru
Veaceslav Mindru

Reputation: 97

Answering my own quesstion, Kudos to John.

Thank's John Anderson. This is the final version. Most important, i am updating text in a function instead of doing it in the KV, and second the increment has to be by TIMER value and not by 1. Latest example can be found here https://github.com/vmindru/amb_pit_timer/blob/main/simple_timer.py

code

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

Upvotes: 0

John Anderson
John Anderson

Reputation: 38857

The problem is that the first animation animates the angle property to 360, and further animations try to animate the angle property to 360 again, which results in no actual animation. The fix is to increment your COUNT after each animation, like this:

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

Upvotes: 1

Related Questions