【问题标题】:Tkinter GUI buttons running loopsTkinter GUI 按钮运行循环
【发布时间】:2020-06-18 18:45:06
【问题描述】:

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

  1. 我在另一个函数中运行 while 循环以在剩余时间内更新标签
  2. 在循环 GUI 无响应时(没关系)
  3. 我搜索了一下,查看了一些 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()

【问题讨论】:

标签: python tkinter


【解决方案1】:

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

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

在 3.5 版更改:即使睡眠被信号中断,该函数现在至少睡眠几秒钟,除非信号处理程序 引发异常(请参阅 PEP 475 了解基本原理)。

另一种方法是使用 .after() 方法。以下是一些链接:

tkinter and time.sleep

How to create a timer using tkinter?

【讨论】:

  • 谢谢,我会浏览文章并返回 :)从您所引用的内容来看,使用睡眠确实不是一个好主意。
  • 干得好,竖起大拇指。
  • 如果你不介意我可以再问一件事吗?为什么如果我调用 threading.Thread(target=playsound).start() - 它可以工作,但如果我这样称呼它:threading.Thread(target=playsound()).start() - 似乎它无限循环?如果我像这样调用计时器函数,它会立即滚降到 0 并抛出和错误达到最大迭代深度或类似的东西。提前致谢!
  • 我从未使用过线程,但这似乎是语法:target=functarget=func()。在第一个示例中,函数被通过,而在第二个示例中,函数被调用。另请参阅文档:docs.python.org/3/library/threading.html#threading.Thread
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-01
  • 2012-04-02
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-07
相关资源
最近更新 更多