我正在尝试编写一个计时器,它应该动态更改标签并显示时间,但标签仅在计数器函数完成工作时才会更改,有人知道我如何做到这一点,或者我只有一种方法 - 异步
这是我的代码(请不要笑),如果你知道如何通过异步方式解决这个问题,请告诉我
import tkinter
from tkinter import *
from PIL import Image, ImageTk
import time
def counter(timer_sum):
start_time = time.time()
time.sleep(timer_sum)
end_time = time.time()
---------------
# here
def change(hours,minutes,seconds):
time_counter_label.config(text=f'{hours}:{minutes}:{seconds}')
--------------
def timer_function_start():
count_time = input_timer.get()
hours_box = int(spin_box_time_hours.get()) * 3600
minute_box = int(spin_box_time_minuts.get()) * 60
second_box = int(spin_box_time_second.get())
timer_sum = hours_box + minute_box + second_box
time_counter_label.config(text=f'{spin_box_time_hours.get()}:{spin_box_time_minuts.get()}:{spin_box_time_second.get()}')
for item in range(timer_sum,0,-1):
hours = int(item /3600) % 60
minutes = int(item / 60) % 60
seconds = item % 60
print(f'{hours}:{minutes}:{seconds}')
change(hours,minutes,seconds)
time.sleep(1)
split_count = count_time.split(':')
# counter(timer_sum)
print("finish")
mainWindow = Tk()
mainWindow.minsize(300, 620)
timerImage = Image.open('img/timer.png')
timerImage = ImageTk.PhotoImage(timerImage)
label_name = tkinter.Label(text='Timer')
label_name.pack()
label_name.config(height=3, width=4, font=("Arial", 24))
image_label = tkinter.Label(mainWindow, image=timerImage)
image_label.config(height=220, width=200)
image_label.pack()
button_timer_start = tkinter.Button(text='Start', command=timer_function_start)
button_timer_start.config(width=4, height=2)
button_timer_start.pack(pady=8)
button_timer_stop = tkinter.Button(text='Stop')
button_timer_stop.config(width=4, height=2)
button_timer_stop.pack()
time_counter_label = tkinter.Label(text='00:00:00')
time_counter_label.config(font=('Arial', 22))
time_counter_label.pack(pady=10)
timer_label = tkinter.Label(mainWindow, text="Enter Time")
timer_label.config(height=3, width=7)
timer_label.pack()
input_timer = tkinter.Entry()
input_timer.pack()
list_time_hours = list(map(lambda x: x, range(0, 24 + 1)))
list_time_minit = list(map(lambda x: x, range(0, 60 + 1)))
list_time_second = list(map(lambda x: x, range(0, 60 + 1)))
spin_box_time_hours = tkinter.Spinbox(mainWindow, values=list_time_hours)
spin_box_time_hours.pack(side=tkinter.LEFT, padx=20)
spin_box_time_hours.config(width=3)
spin_box_time_minuts = tkinter.Spinbox(mainWindow, values=list_time_minit)
spin_box_time_minuts.pack(side=tkinter.LEFT, padx=20)
spin_box_time_minuts.config(width=3)
spin_box_time_second = tkinter.Spinbox(mainWindow, values=list_time_second)
spin_box_time_second.pack(side=tkinter.LEFT, padx=20)
spin_box_time_second.config(width=3)
mainWindow.mainloop()
如果您正在开发 tkinter 应用程序并需要定期更新 UI,请不要使用
time.sleep()
。它会阻塞主线程,从而阻止 UI 在睡眠结束之前更新。相反,请使用 tkinter 中的 after()
方法。这会安排在指定时间后调用一个函数,而不会阻塞主线程。
要使其正常工作,请像这样修改您的
timer_function_start
函数:
def timer_function_start():
# ... your existing setup code for timer_sum ...
countdown(timer_sum)
def countdown(time_left):
if time_left > 0:
hours = int(time_left / 3600) % 60
minutes = int(time_left / 60) % 60
seconds = time_left % 60
time_counter_label.config(text=f'{hours:02d}:{minutes:02d}:{seconds:02d}')
# Schedule the countdown function to be called after 1000ms (1 second)
mainWindow.after(1000, countdown, time_left - 1)
else:
print("finish")