在我的程序中,我想在用户输入时更新我的gui。出于资源原因,我只想在用户没有键入x毫秒的内容时这样做。这是一个有效的例子,但我不太喜欢它,因为它需要两个额外的功能,而且有点冗长。
import tkinter as tk
import random
COLORS =["red", "orange", "yellow", "green", "blue", "violet"]
class Application(tk.Frame):
def __init__(self,master):
self.counter = 0
self.master = master
tk.Frame.__init__(self)
self.pack()
self.entry = tk.Entry(self)
self.entry.pack()
self.entry.bind('<Key>',lambda event: self.handle_wait(event))
def handle_wait(self,event):
self.counter += 1
counter = self.counter
self.after(1000,lambda: self.handle_wait2(counter) )
def handle_wait2(self,counter):
if self.counter == counter:
self.change_color()
def change_color(self):
random_color = random.choice(COLORS)
self.entry.config(background=random_color)
root = tk.Tk()
app = Application(root)
app.mainloop()
有更好的方法吗?
答案 0 :(得分:2)
解决方案是使用after
来安排在用户停止输入后运行的功能。然后,您需要做的就是每次单击按钮时重新启动作业。
首先,创建一个变量来存储表示未来函数调用的id。您也可以丢弃self.counter
,因为它不需要。
def __init__(...):
...
self._after_id = None
...
接下来,删除绑定中的lambda。它毫无意义,使代码更加复杂:
self.entry.bind('<Key>',self.handle_wait)
最后,将您的handle_wait
功能更改为:
def handle_wait(self, event):
# cancel the old job
if self._after_id is not None:
self.after_cancel(self._after_id)
# create a new job
self.after(1000, self.change_color)
以下是基于您的代码的完整示例:
import tkinter as tk
import random
COLORS =["red", "orange", "yellow", "green", "blue", "violet"]
class Application(tk.Frame):
def __init__(self,master):
self.master = master
tk.Frame.__init__(self)
self.pack()
self._after_id = None
self.entry = tk.Entry(self)
self.entry.pack()
self.entry.bind('<Key>',self.handle_wait)
def handle_wait(self,event):
# cancel the old job
if self._after_id is not None:
self.after_cancel(self._after_id)
# create a new job
self._after_id = self.after(1000, self.change_color)
def change_color(self):
random_color = random.choice(COLORS)
self.entry.config(background=random_color)
root = tk.Tk()
app = Application(root)
app.mainloop()