I am trying to create a Timer using tkinter and python. To start and reset the timer there are two buttons Three Entry fields to get the hours, minutes, and seconds and a Label to display the decreasing countdown time.
But as soon i set a time and click the start button, the time in label is 1 second less than the entered time and the timer ends 1 second after the text in label becomes "00:00:00".Means the time is out of sync by 1 second.
I want the same time to be copied from EntryFields to the label and sync the time.
'''
import time
from tkinter import *
from tkinter.messagebox import *
root = Tk()
root.title("Timer Application")
root.geometry("600x400")
running = 0
hours = StringVar()
mins = StringVar()
secs = StringVar()
string = StringVar()
hrText = Entry(root,font = ("Arial", 20), width=2, textvariable=hours,borderwidth=5)
minText = Entry(root,font = ("Arial", 20), width=2, textvariable=mins,borderwidth=5)
secText = Entry(root,font=("Arial",20), width=2,textvariable=secs,borderwidth=5)
lbl = Label(root, text="00:00:00" , font=('Arial',20),relief=GROOVE,borderwidth=3)
hrText.insert(0,"00")
minText.insert(1,"00")
secText.insert(2,"00")
lbl['text'] = "00:00:00"
hrText.place(x=200,y=100)
minText.place(x=260,y=100)
secText.place(x=320,y=100)
def start():
running=1
if set_timer():
run_timer()
def set_timer():
if int(hours.get()) >=0 and int(mins.get())>=0 and int(secs.get())>=0:
string = "{:2s}:{:2s}:{:2s}".format(hours.get(), mins.get(), secs.get())
lbl['text'] = string
hrText.config(state=DISABLED)
minText.config(state=DISABLED)
secText.config(state=DISABLED)
time.sleep(1)
return True
else:
showinfo("Wrong Input","Enter a valid time")
return False
def run_timer():
running = 1
h,m,s = [int(x) for x in lbl['text'].split(':')]
tot_secs = h*3600 + m*60 + s
if running:
if tot_secs:
if s>0:
s-=1
elif s==0:
if m>0:
m-=1
s=59
elif m==0:
if h:
h-=1
m=59
s=59
if tot_secs:
lbl['text'] = str(h)+":"+str(m)+":"+str(s)
lbl.after(1000,run_timer)
else:
return
# if tot_secs>0:
elif tot_secs==0:
running=0
showinfo(title="Complete",message="Time's Up.")
return None
def reset():
running=0
hrText.config(state=NORMAL)
minText.config(state=NORMAL)
secText.config(state=NORMAL)
# secText.config(setfocus=1)
hours.set("00")
mins.set("00")
secs.set("00")
lbl['text']="00:00:00"
lbl.place(x = 180, y= 250, width= 200)
bt = Button(root, text="Start",font=("Consolas", 16),command = start).place(x=300, y= 182)
bt = Button(root, text="Reset", font=("Consolas", 16),command=reset).place(x=180, y = 182)
root.mainloop()
'''
time.sleep(1)after you set the label text, thenrun_timer()is executed which decrease the timer by 1 and update the label text. That's why you cannot see the initial time. Addlbl.update()beforetime.sleep(1)to fix it. The second issue is that whentot_secsis 1 whenrun_timer()is executed, the timer will be decreased by 1 so that h=m=s=0 and the label is updated with "0:0:0" and calllbl.after(1000, run_timer). So one second later,run_timer()is called andtot_secsis zero and then show the "Time's Up" message. - acw1668