When you press "reset" button, the stopwatch is supposed to stop and reset, but instead it sets digits to zero, then adds one more second and ends up with 00:00:01.
The same with "stop" button. F.e. if we press stop at 00:05, it stops with 00:06. Plus one second every time. But sometimes you can click at the right moment, at the very beginning of the current second so it won't happen.
I tried after_cancel
, didn't help.
It's impossible to run debugging in VScode because break points block buttons while the time is going, so I can't trigger the function.
I followed several tutorials and every time I implement pieces of their code, I get this issue.
Why does it happen? Where this 1 second comes from and how to fix?
from tkinter import *
root = Tk()
switch = False
def start():
global switch
switch = True
def stop():
global switch
switch = False
# Stopwatch variables
seconds = 0
minutes = 0
hours = 0
# Stopwatch functions
def stopwatch_update():
global seconds, minutes, hours
seconds = 1
if seconds == 60:
minutes = 1
seconds = 0
if minutes == 60:
hours = 1
minutes = 0
hours_string = f'{hours}' if hours > 9 else f'0{hours}'
minutes_string = f'{minutes}' if minutes > 9 else f'0{minutes}'
seconds_string = f'{seconds}' if seconds > 9 else f'0{seconds}'
stopwatch_label.config(text = hours_string ':' minutes_string ':' seconds_string)
if switch:
stopwatch_label.after(1000, stopwatch_update)
def stopwatch_func(command):
if command == 'start':
start()
stopwatch_start.config(state='disabled')
stopwatch_stop.config(state='normal')
stopwatch_reset.config(state='normal')
stopwatch_update()
if command == 'stop':
stopwatch_start.config(state='normal')
stopwatch_stop.config(state='disabled')
stop()
if command == 'reset':
stopwatch_start.config(state='normal')
stopwatch_stop.config(state='disabled')
stop()
global hours, minutes, seconds
hours, minutes, seconds = 0, 0, 0
stopwatch_label.config(text='00:00:00')
# Stopwatch components
stopwatch_label = Label(root, font='calibri 20', text='Stopwatch')
stopwatch_label.pack()
stopwatch_start = Button(root, text='Start', command=lambda: stopwatch_func('start'))
stopwatch_start.pack()
stopwatch_stop = Button(root, text='Stop', state='disabled',command=lambda:stopwatch_func('stop'))
stopwatch_stop.pack()
stopwatch_reset = Button(root, text='Reset', state='disabled', command=lambda:stopwatch_func('reset'))
stopwatch_reset.pack()
mainloop()
CodePudding user response:
Defined a variable for stopwatch_label.after(1000, stopwatch_update)
and now everything works fine.
The end of stopwatch_update()
:
if switch:
global stopwatch_after
stopwatch_after = stopwatch_label.after(1000, stopwatch_update)
stopwatch_func(command)
is also updated for "stop" and "reset" commands:
if command == 'stop':
stopwatch_start.config(state='normal')
stopwatch_stop.config(state='disabled')
stop()
stopwatch_label.after_cancel(stopwatch_after)
if command == 'reset':
stopwatch_start.config(state='normal')
stopwatch_stop.config(state='disabled')
stop()
global hours, minutes, seconds
hours, minutes, seconds = 0, 0, 0
stopwatch_label.config(text='00:00:00')
stopwatch_label.after_cancel(stopwatch_after)