Tkinter GUI按钮运行循环

时间:2020-06-18 18:45:06

标签: python tkinter

我正在尝试学习如何使用TKinter为Python应用程序制作GUI。我正在尝试创建一个Pomodoro计时器,但是遇到了两个问题。

  1. 我在另一个函数中运行while循环以用剩余时间更新标签
  2. 虽然循环GUI没有响应(没关系)
  3. 我在Google上进行了一些搜索,遇到了一些StackOverflow问题,并且发现该函数运行循环可以在单独的线程中运行。

这解决了第一个问题,但还有另一个问题

  1. 取消按钮有效,但是我看不到点击动画。
  2. 计时器不会立即停止。

您能否解释一下为什么会发生这种情况以及我可以做些什么来提高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()

1 个答案:

答案 0 :(得分:0)

通常不建议使用sleep(),尤其是在多线程时。睡眠“至少”等待一段时间,但是由于其他进程,代码执行可能不会重新开始。这就是文档所说的:

以给定数目的中断执行调用线程 秒。参数可以是浮点数,以指示 更精确的睡眠时间。实际的暂停时间可能少于 该请求,因为任何捕获到的信号都会终止sleep() 在执行该信号的捕获例程之后另外, 暂停时间可能比要求的时间长任意数量 由于系统中其他活动的安排。

在版本3.5中进行了更改:现在,即使睡眠被信号中断,该函数也可以睡眠至少sec,除非信号处理程序 引发异常(有关原理,请参阅PEP 475)。

替代方法是使用.after()方法。这里是一些链接:

tkinter and time.sleep

How to create a timer using tkinter?