Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kivy simple countdown minute and second timer

So I want to build a kivy program that basically just countdown a certain minutes and seconds.

this is how far I have come:

from kivy.app import App
from kivy.uix.label import Label
from kivy.clock import Clock

from datetime import datetime, date, time


class IncrediblyCrudeClock(Label):
    a = time(0, 1, 1)
    
    def update(self, *args):
        self.text = str(self.a)
        print(str(self.a))

        self.a = datetime.combine(date.today(), self.a) - datetime.combine(date.today(), time(0,0,1))

class TimeApp(App):
    def build(self):
        crudeclock = IncrediblyCrudeClock()
        Clock.schedule_interval(crudeclock.update, 1)
        return crudeclock

if __name__ == "__main__":
    TimeApp().run()

the problem is that when I try to deduct the old time from the new time, so that I have 1 second less displayed, I get the following error:

self.a = datetime.combine(date.today(), self.a) datetime.combine(date.today(), time(0,0,1))
 TypeError: combine() argument 2 must be datetime.time, not datetime.timedelta

this makes me think that, after the first subtraction, a is now not a "time" object anymore, but a "timedelta" which unfortunately can not be deducted.

any help would be great!

like image 584
Cid-El Avatar asked Sep 14 '26 07:09

Cid-El


1 Answers

There is a simpler approach if you just need a countdown. You can use kivy's Animation class which is described very nicely by @inclement on youtube. So here's the code (main.py and time.kv):

main.py

from kivy.app import App
from kivy.uix.label import Label
from kivy.animation import Animation
from kivy.properties import StringProperty, NumericProperty


class IncrediblyCrudeClock(Label):
    a = NumericProperty(5)  # seconds

    def start(self):
        Animation.cancel_all(self)  # stop any current animations
        self.anim = Animation(a=0, duration=self.a)
        def finish_callback(animation, incr_crude_clock):
            incr_crude_clock.text = "FINISHED"
        self.anim.bind(on_complete=finish_callback)
        self.anim.start(self)

class TimeApp(App):
    def build(self):
        crudeclock = IncrediblyCrudeClock()
        crudeclock.start()
        return crudeclock

if __name__ == "__main__":
    TimeApp().run()

time.kv

<IncrediblyCrudeClock>
    text: str(round(self.a, 1))

Enjoy! :)


Update:

The OP requested a solution without a kv-file -- so here is one:

from kivy.app import App
from kivy.uix.label import Label
from kivy.animation import Animation
from kivy.properties import StringProperty, NumericProperty


class IncrediblyCrudeClock(Label):
    a = NumericProperty(5)  # seconds

    def start(self):
        Animation.cancel_all(self)  # stop any current animations
        self.anim = Animation(a=0, duration=self.a)
        def finish_callback(animation, incr_crude_clock):
            incr_crude_clock.text = "FINISHED"
        self.anim.bind(on_complete=finish_callback)
        self.anim.start(self)

    def on_a(self, instance, value):
        self.text = str(round(value, 1))

class TimeApp(App):
    def build(self):
        crudeclock = IncrediblyCrudeClock()
        crudeclock.start()
        return crudeclock

if __name__ == "__main__":
    TimeApp().run()
like image 106
yogabonito Avatar answered Sep 16 '26 22:09

yogabonito



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!