等到用户停止在Tkinter中输入

时间:2016-05-25 09:13:03

标签: python tkinter

在我的程序中,我想在用户输入时更新我的​​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()

有更好的方法吗?

1 个答案:

答案 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()