Hi friends!
I want to create a countdown program. Here is my code:

from kivy.app import App

from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label

import datetime

class CountdownApp(App):
    def build(self):

        delta = datetime.datetime(2015, 3, 21, 2, 15, 11) - datetime.datetime.now()
        days = delta.days
        days = str(days)
        self.label_days = Label(text=days + "  days")

        hour_string = str(delta).split(', ')[1]
        hours = hour_string.split(':')[0]
        self.label_hours = Label(text=hours + "  hours")

        minuts = hour_string.split(':')[1]
        self.label_minuts = Label(text=minuts + "  minuts")

        seconds = hour_string.split(':')[2]
        self.label_seconds = Label(text=seconds + "  seconds")



        b = BoxLayout(orientation="vertical")
        b.add_widget(self.label_days)
        b.add_widget(self.label_hours)
        b.add_widget(self.label_minuts)
        b.add_widget(self.label_seconds)
        return b

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

I want the program to update itself every seconds and then the label wich shows seconds should be updated every seconds....
How can i do that?

Dani AI

Generated

Nice start! In Kivy you do not want a while True or time.sleep; that blocks the UI thread and will freeze your app. was on the right track: schedule a callback on the Clock and recompute the remaining time each tick. The dt arg Kivy passes into your callback is the elapsed time (in seconds) since the previous tick; you do not need it here, but it is handy to account for drift in other animations.

Here is a minimal pattern you can drop in. Notice we:

  • store the target datetime on self,
  • create labels once in build(),
  • schedule update() every 1 second,
  • recompute remaining time from datetime.now() each tick,
  • stop the timer cleanly when it reaches zero.
from datetime import datetime
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.clock import Clock

class CountdownApp(App):
    def build(self):
        self.target = datetime(2015, 3, 21, 2, 15, 11)

        self.lbl_days = Label()
        self.lbl_hours = Label()
        self.lbl_minutes = Label()
        self.lbl_seconds = Label()

        root = BoxLayout(orientation="vertical")
        for w in (self.lbl_days, self.lbl_hours, self.lbl_minutes, self.lbl_seconds):
            root.add_widget(w)

        Clock.schedule_interval(self.update, 1.0)
        self.update(0)  # update immediately so the UI is not blank
        return root

    def update(self, dt):
        total = int((self.target - datetime.now()).total_seconds())
        if total <= 0:
            total = 0
            Clock.unschedule(self.update)

        days, rem = divmod(total, 86400)
        hours, rem = divmod(rem, 3600)
        minutes, seconds = divmod(rem, 60)

        self.lbl_days.text = "{} days".format(days)
        self.lbl_hours.text = "{:02d} hours".format(hours)
        self.lbl_minutes.text = "{:02d} minutes".format(minutes)
        self.lbl_seconds.text = "{:02d} seconds".format(seconds)

Tip: avoid parsing str(timedelta) as in your original; it changes format for long spans and negative values. Also, if your target is in another timezone or crosses a DST change, prefer timezone-aware datetimes to avoid a one-hour jump.

Recommended Answers

All 5 Replies

you could try to use kivy's Clock module

from kivy.clock import Clock

class CountdownApp(App):
    def build(self):
        t = 1.0 / 60.0 # 1/60th of a second, use 1.0 instead to update every second
        Clock.schedule_interval(self.update, t)

        # some other code ....

    def update(self, dt):
        # update things - your labels?

, what is that dt in line 10 for?

I refer you to this Kivy Clock. :) I'm not really well versed with kivy. I do know dt means delta-time. :)

Well, i stil have problem with this program, what should i type in line 11, for the update function?!

All my code that should be updated every seconds, are in the build function in the CountdownApp class.

the easiest way would be wraping the part you want in a while True loop and then putting a time.sleep(1) at the start of that loop or at the end of that so it will make a 1 second delay to update the loop , so your countdown .

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.