[Tutor] Countdown Clock Programming Question
Alan Gauld
alan.gauld at btinternet.com
Tue Nov 24 13:19:22 EST 2015
On 24/11/15 14:01, Evan Sommer wrote:
> goal is for the clock to change from green to yellow at 2 minutes, and
> yellow to red at 1 minute.
> def count_down():
> # start with 4 minutes --> 240 seconds
> for t in range(240, 120, -1):
> # format as 2 digit integers, fills with zero to the left
> # divmod() gives minutes, seconds
> sf = "{:01d}:{:02d}".format(*divmod(t, 60))
> #print(sf) # test
> time_str.set(sf)
> root.update()
> # delay one second
> time.sleep(1)# create root/main window
Its not recommended to use sleep in a GUI program, the Tkinter
library provides the after() method to do this instead. In
your case you'd call it with a timeout of 1000ms
Also because sleep() and after() are rather imprecise in their
timings it will be more accurate to use the time module to get
the actual start time and then on each update fetch that again
and compute the difference. (Although I doubt it will make
much difference over 4 minutes!)
eg
target_time = time.time() + 240 # now plus 4 min
and then
display_period = target_time - time.time() # accurate seconds left
> root = tk.Tk()
> time_str = tk.StringVar()
> # create the time display label, give it a large font
> # label auto-adjusts to the font
> label_font = ('helvetica', 100)
> tk.Label(root, textvariable=time_str, font=label_font, bg='green',
> fg='white', relief='raised', bd=3).pack(fill='x', padx=5, pady=5)
It would be better to create the label once and then
just change its colours. But for that you need to
store a reference to it:
timeLabel = tk.Label(root, textvariable=time_str,
font=label_font, bg='green',
fg='white', relief='raised',
bd=3).pack(fill='x', padx=5, pady=5)
I'd also miss out the Stringvar and just update the text
attribute directly. Stringvar is great when you want two
way interaction with a field but for a label it doesn't really
help, IMHO.
> # start with 2 minutes --> 119 seconds
> for t in range(240, 120, -1):
> # format as 2 digit integers, fills with zero to the left
> # divmod() gives minutes, seconds
> sf = "{:01d}:{:02d}".format(*divmod(t, 60))
> #print(sf) # test
> time_str.set(sf)
> root.update()
> # delay one second
> time.sleep(1)
> # create the time display label, give it a large font
> # label auto-adjusts to the font
> label_font = ('helvetica', 100)
You already defined label_font no need to do it again.
> tk.Label(root, textvariable=time_str, font=label_font, bg='yellow',
> fg='white', relief='raised', bd=3).pack(fill='x', padx=5, pady=5)
> # start with 1 minutes --> 59 seconds
Doesn't this create a second label on your display?
Or do you delete the old one somewhere that I haven't seen?
> for t in range(120,60, -1):
> # format as 2 digit integers, fills with zero to the left
> # divmod() gives minutes, seconds
> sf = "{:01d}:{:02d}".format(*divmod(t, 60))
> #print(sf) # test
> time_str.set(sf)
> root.update()
> # delay one second
> time.sleep(1)
> # create the time display label, give it a large font
> # label auto-adjusts to the font
> label_font = ('helvetica', 100)
> tk.Label(root, textvariable=time_str, font=label_font, bg='red',
> fg='white', relief='raised', bd=3).pack(fill='x', padx=5, pady=5)
> # start with 4 minutes --> 240 seconds
See previous comments re duplicating code.
> for t in range(60,-1, -1):
> # format as 2 digit integers, fills with zero to the left
> # divmod() gives minutes, seconds
> sf = "{:01d}:{:02d}".format(*divmod(t, 60))
> #print(sf) # test
> time_str.set(sf)
> root.update()
> # delay one second
> time.sleep(1)
> # start the GUI event loop
> root.mainloop()
>
Personally I'd do it in a pair of functions that look
loosely like
def initialise():
set up GUI
create label with startuing font/size/color
target_time = time.time() + 240
label[text] = "4:00"
after(1000, update_display)
def update_display()
display_period = target_time - time.time()
min,sec = divmod(display_period,60)
if min < 2: set color to yellow
elif: min < 1: set color to red
else: set color to green
set label text to min/sec
after(1000, update_display)
No loops required and no repeated code.
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos
More information about the Tutor
mailing list