我正在尝试学习如何使用TKinter为Python应用程序制作GUI。我正在尝试创建一个番茄钟计时器,但是我遇到了几个问题。
- 我在另一个函数中运行
while
循环以更新标签剩余时间 - 在循环 GUI 无响应时(没关系(
- 我用谷歌搜索了一下,浏览了一些 StackOverflow 问题,我发现这个函数运行循环可以在单独的线程中运行。
这解决了第一个问题,但还有另一个问题
- 取消按钮有效,但我看不到点击动画。
- 计时器不会立即停止。
您能否解释为什么会发生这种情况以及我可以做些什么来提高 GUI 的响应能力?
import time
import tkinter
import winsound
from tkinter.ttk import Combobox
import threading
def run_thread():
global stop
stop = False
start_timer_btn.grab_release()
threading.Thread(target=countdown()).start()
def stop_timer():
global stop
stop = True
def countdown():
option = combo.get()
if option == "25":
seconds = 1500
elif option == "15":
seconds = 900
# elif option == "2":
# countdown(300)
# elif option == "3":
# countdown(1200)
global stop
while seconds and not stop:
seconds -= 1
print("minutes", seconds // 60, "seconds", seconds % 60)
timer_label.configure(text=str(seconds // 60) + ":" + str(seconds % 60))
window.update()
time.sleep(1)
winsound.PlaySound("SystemExit", winsound.SND_ALIAS)
stop = False
window = tkinter.Tk()
window.title("POMODORO Timer")
window.geometry("300x250")
combo = tkinter.ttk.Combobox(window)
combo["values"] = [25, 15]
combo.current(1)
timer_label = tkinter.Label(window, text="00:00")
start_timer_btn = tkinter.Button(window, text="Start timer", bg="green", fg="white", command=run_thread)
stop_timer_btn = tkinter.Button(window, text="Stop timer", bg="red", fg="white", command=stop_timer)
combo.grid(row=1, column=0)
start_timer_btn.grid(row=1, column=1)
stop_timer_btn.grid(row=1, column=2)
timer_label.grid(row=0, column=2, columnspan=3)
window.mainloop()
通常不鼓励使用 sleep((,尤其是在多线程时。睡眠"至少"等待一段时间,但由于其他进程,代码执行可能不会重新启动。文档是这样说的:
暂停执行给定数量的调用线程 秒。参数可以是浮点数,以指示 更精确的睡眠时间。实际暂停时间可能小于 请求,因为任何捕获的信号都将终止 sleep(( 在执行该信号的捕获例程之后。此外, 暂停时间可能比任意请求的长度长 因为系统中其他活动的调度。
在 3.5 版更改: 即使睡眠被信号打断,该函数现在至少休眠几秒钟,除非信号处理程序 提出一个例外(有关基本原理,请参阅 PEP 475(。
另一种方法是使用 .after(( 方法。以下是一些链接:
tkinter 和 time.sleep
如何使用 tkinter 创建计时器?