我有一个TKinter应用程序(Python),该应用程序对按钮按下和键盘输入有反应。但是,在这些事件之一之后调用的函数可能需要花费一些时间才能执行。我希望GUI在函数执行时拒绝所有用户输入。 [编辑:只是要澄清:所有用户输入指的是应用程序中存在的所有按钮/键绑定-我不仅仅是在拒绝特定按钮的事件。] >
这是一个非常简单的示例,它表明TKinter当前似乎将事件添加到队列中,该队列在处理每个事件之后执行。每次按下按钮时,按钮中的文本都会附加一个零。但是,如果在文本显示为00
时按下了按钮,则该函数需要一段时间才能执行(我放入了self.after(3000)),如果在执行该函数时按下了按钮,则这些印刷机中的每一个都会注册。因此,如果我在3秒钟内将按钮“停顿”了5次,则每次单击都会记录下来,最终我会在按钮上看到0000000
。
import tkinter as tk
# To demonstrate that keystrokes/button clicks do register while a function is executing (and then subsequently fire)
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
# Build the app
self.text = tk.StringVar()
self.pack()
self.create_widgets()
def create_widgets(self):
self.btn = tk.Button(self, textvariable=self.text, command=self.DoSomething, padx=30, pady=30)
self.btn.grid(row=0, column=0)
self.text.set('0')
def DoSomething(self):
# self.RejectEventsWhileThisFuncExecutes()
old_msg = self.text.get()
if old_msg == '00':
self.after(3000)
self.text.set(old_msg + '0')
# self.BeginAcceptingEventsAgain()
root = tk.Tk()
app = Application(master=root)
app.mainloop()
基本上,我想要的可能是我可以在函数的开头和结尾处在DoSomething()
中调用的内容,例如self.RejectEventsWhileThisFuncExecutes()
和self.BeginAcceptingEventsAgain()
,这可以确保不会函数执行时会记录点击。
答案 0 :(得分:1)
您可以从DoSomething
开始的按钮中删除命令:
self.btn.config(command=lambda: None)
然后在最后将其重置。只需在重新绑定之前确保update
处理所有排队的事件:
self.update()
self.btn.config(command=self.DoSomething)
答案 1 :(得分:1)
一种常见的策略是创建一个不可见的窗口小部件(例如:窗口角处的1x1帧),然后对该窗口小部件进行抓取(即:调用grab_set
)。这导致所有事件都被漏斗到该小部件。只要该窗口上没有绑定,最终的结果就是事件将被忽略。您只需要先清除事件队列(调用update
方法),然后再删除抓斗。