在达到一定的可变延迟后调用 tkinter 跟踪回调

Invoke tkinter trace callback AFTER a certain variable delay has been achieved

我有一个 tkinter 应用程序,当用户输入 Entry 小部件时,它会搜索大约 100000 个单词列表(使用带有写入回调的跟踪来捕获 Entry 变量中的变化)。

我想实现某种延迟,以便调用跟踪回调(搜索整个 100k 词表)在每次击键时[=21] =](因为用户可能仍在打字,它可以变得相当 jerky/slow 为每次击键调用回调函数),而我想使用某种 的最短时间来等待额外的input/keystroke AND/OR 自按下第一个键以来的最长时间 调用跟踪回调函数之前。

我尝试实现睡眠,但这只是一个阻塞调用,并没有达到预期的效果。这是一些示例代码,其中输入字符串 'password' 将调用回调(因为这实际上只是检查字符串 'password',速度非常快,但在我的应用程序中我循环了 100k 单词列表每次击键都会变慢)。谢谢!

import tkinter as tk
from tkinter import ttk

class App(tk.Tk):
    SUCCESS = 'Success.TLabel'

    def __init__(self):
        super().__init__()
        self.title('Enter <password>')
        self.geometry("200x120")
        self.passwordVariable = tk.StringVar()
        self.passwordVariable.trace('w', self.validate)
        password_entry = ttk.Entry(
            self, textvariable=self.passwordVariable) #, show='*'
        password_entry.grid(column=0, row=1)
        password_entry.focus()
        self.message_label = ttk.Label(self)
        self.message_label.grid(column=0, row=0)

    def set_message(self, message, type=None):
        self.message_label['text'] = message
        if type:
            self.message_label['style'] = type

    def validate(self, *args):
        confirm_password = self.passwordVariable.get()
        if confirm_password == "password":
            self.set_message(
                "Success: The new password looks good!", self.SUCCESS)
            return
        if confirm_password.startswith("pas"):
            self.set_message('Warning: Keep entering the password')

if __name__ == "__main__":
    app = App()
    app.mainloop()

我试图了解您当前代码的作用,以便我可以在此处实现 函数,但我没有成功。希望您作为作者可以在您的代码中实现这个示例。

这里的想法是在 x 秒后安排回调到 运行,如果已经安排好,则取消它。如果您考虑一下,有点像计时器。

from tkinter import *

root = Tk()
SECONDS_TO_WAIT = 1
rep = None

def typing(*args):
    global rep
    if rep is None:
        writing.config(text='Typing...')
    else:
        root.after_cancel(rep) # if already scheduled, then cancel it
    
    rep = root.after(SECONDS_TO_WAIT*1000, caller) 

def caller(*args):
    global rep
    writing.config(text='Not typing')
    rep = None # Set it to None if `caller` GETS executed

var = StringVar()
entry = Entry(root,textvariable=var)
entry.pack(padx=10,pady=10)
entry.focus_force()

writing = Label(root,text='Not typing')
writing.pack()
var.trace('w',typing)

root.mainloop()

每次输入小部件 edited/written 时,这将执行 typing。并且根据函数内部的条件,caller被执行。