添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

I want the button to start the command, then be disabled while executing and enabled again after the execution finished.

When I click the button, it appears to be disabled and the command is executed. But when I click the button while it is disabled, the command is executed a second time after it finished the first execution.

It seems like after the second click, the button is really disabled because I can click several times while it's disabled and it's only repeated once.

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()
                Very strange. effbot.org/tkinterbook/widget.htm#Tkinter.Widget.update-method suggests not using update inside a callback, but switching to update_idletasks only makes the problem worse - instead of permitting two clicks, it permits an unlimited number of clicks.
                    – Kevin
                Apr 5 '19 at 12:56
                tkinter runs all in one thread. When you run long-running proces - like sleep - it stops mainloop and it can't correctly update widgets. Sometimes it looks like window freeze (hangs up). You should run long-running process in new thread
                    – furas
                Apr 5 '19 at 13:10
                You should change your class name "Button" because tkinter has already a Button class. This will not fix your problem but it should be done. I know you imported tkinter as tk but still.
                    – user10474264
                Apr 5 '19 at 13:12
        

When you click the button during the sleep, you queue a button click to be processed in the next update cycle. During the sleep tkinter doesn't update. After the sleep, you change the button back to normal state before the function returns and the click is processed. Since the button is active again, click is called again.

You can counter this by letting tkinter update before you activate the button again, this gets rid of any queued click events while the button still is deactivated.

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")
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.

site design / logo © 2020 Stack Exchange Inc; user contributions licensed under cc by-sa 4.0 with attribution required. rev 2020.2.25.36142