【问题标题】:Tkinter Button still responds to click after being disabled and updatedTkinter Button 在被禁用和更新后仍然响应点击
【发布时间】:2019-04-05 12:33:18
【问题描述】:

我希望按钮启动命令,然后在执行时禁用并在执行完成后再次启用。

当我单击按钮时,它似乎被禁用并且命令被执行。但是当我在按钮被禁用时单击该按钮时,该命令在完成第一次执行后第二次执行。

似乎在第二次单击后,该按钮确实被禁用了,因为我可以在它被禁用时单击几次,并且只重复一次。

import tkinter as tk
import time


class Button:
    def __init__(self, master):
        frame=tk.Frame(master)
        frame.pack()
        self.button1=tk.Button(frame, text="Ready",bg="green", fg="white", command=self.click)
        self.button1.pack()

    def click(self):
        self.button1.config(bg="red", text="Busy", state="disabled")
        self.button1.update()
        doSth()
        self.button1.config(bg="green", fg="white", text="Ready", state="normal")
        self.button1.update()


def doSth():
    time.sleep(3)
    print("done")


root = tk.Tk()
b = Button(root)
root.mainloop()

【问题讨论】:

  • 很奇怪。 effbot.org/tkinterbook/widget.htm#Tkinter.Widget.update-method 建议不要在回调中使用update,但切换到update_idletasks 只会让问题变得更糟——它不允许两次点击,而是允许无限次点击。
  • tkinter 在一个线程中运行。当您运行长时间运行的进程时 - 例如 sleep - 它会停止 mainloop 并且它无法正确更新小部件。有时它看起来像窗口冻结(挂断)。您应该在新线程中运行长时间运行的进程
  • 您应该更改您的类名“Button”,因为 tkinter 已经有一个 Button 类。这不会解决您的问题,但应该这样做。我知道您将 tkinter 导入为 tk 但仍然如此。

标签: python user-interface tkinter


【解决方案1】:

当您在sleep 期间单击按钮时,您会排队等待在下一个更新周期中处理的按钮单击。在sleep tkinter 期间没有更新。在sleep 之后,您将按钮更改回正常状态,然后函数返回并处理单击。由于按钮再次处于活动状态,因此再次调用click

您可以通过让 tkinter 在您再次激活按钮之前更新来解决此问题,这会在按钮仍处于停用状态时消除任何排队的点击事件。

def click(self):
    self.button1.config(bg="red", text="Busy", state="disabled")
    self.button1.update()
    doSth()
    self.button1.update()
    self.button1.config(bg="green", fg="white", text="Ready", state="normal")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    • 1970-01-01
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多