我在Python的tkinter应用程序中有一个条目。如果用户更改了输入内容,程序将通过onValidate
函数做出反应。
现在,如果用户有一段时间没有按任何键,那么我想在输入字段中选择所有文本。
下面,我尝试使用select_all_text
函数在1000
毫秒后after
,但是似乎不起作用。
import tkinter as tk
class MyEntry(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.vcmd = (self.register(self.onValidate),
'%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
self.entry = tk.Entry(self, validate="key", validatecommand=self.vcmd)
self.entry.pack(side="top", fill="x")
self.select_all_text()
def select_all_text(self):
self.entry.focus()
self.entry.select_range(0,'end')
def onValidate(self, d, i, P, s, S, v, V, W):
self.root.after(1000, self.select_all_text)
return True
if __name__ == "__main__":
root = tk.Tk()
MyEntry(root).pack(fill="both", expand=True)
root.mainloop()
此外,每次按下新键时,计时器都应重置,以使select_all_text
仅在自上次按下按键以来经过足够长的时间后才被调用。在下面的示例中,每次按键后都会调用select_all_text
,这是不希望的行为。
我当时想这可以跟踪自上次按键以来的时间,如果超过某个阈值,则会调用该函数。这种方法也可以解决问题。
如果自从tkinter上一次按下按键以来已经足够长的时间,如何调用函数?
答案 0 :(得分:2)
当您保留对after
返回的ID的引用时,可以使用after_cancel
取消它。这样,您可以取消计划的功能并在每次按键时重新计划:
class MyEntry(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.after_id = None
...
def onValidate(self, d, i, P, s, S, v, V, W):
if self.after_id:
self.parent.after_cancel(self.after_id)
self.after_id = self.parent.after(1000, self.select_all_text)
return True
请注意,我还将保存的根窗口作为参数传递给MyEntry
中的self.parent
,并用它来调用after
。
P.S。您实际上并不需要Entry的validatecommand
命令(但是如果您已经使用validatecommand
当然可以,则可以)。您可以将该功能绑定到每个按键:
class MyEntry(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.after_id = None
self.entry = tk.Entry(self)
self.entry.bind('<Key>', self.entry_keypress)
...
def entry_keypress(self, e):
print(self.after_id)
if self.after_id:
self.parent.after_cancel(self.after_id)
self.after_id = self.parent.after(1000, self.select_all_text)