在 tk.Entry 文本变量上调用 tk.StringVar.set() 会导致 validate="focusout" 停止调用
Calling tk.StringVar.set() on a tk.Entry textvariable causes validate="focusout" to stop getting called
问题在标题中,本质上是:如何让 validatecommand
回调在设置条目的 textvariable
后继续被调用?这是最小工作示例 (MWE):
import tkinter as tk
root = tk.Tk()
sv = tk.StringVar()
def callback():
print(sv.get())
sv.set('Set Text.')
return True
e = tk.Entry(root, textvariable=sv, validate="focusout",
validatecommand=callback)
e.grid()
e = tk.Entry(root)
e.grid()
root.mainloop()
请注意,第二个 tk.Entry
小部件可以让第一个小部件失去焦点,这是我们试图捕获的事件。
就像现在的代码一样,当您 运行 它时,您可以更改一次顶部条目小部件的文本。它会正确设置为 Set Text.
然后,如果您尝试再次更改条目的文本,新文本将出现在小部件中,但回调不会发生。
另一方面,如果您注释掉 sv.set('Set Text.')
代码,此行为将完全消失,您可以根据需要多次调用回调。
How can I have the sv.set()
functionality, while still maintaining the callback getting called every time the Entry widget loses focus?
这在 Tk manual page for entry
中讨论:
The validate
option will also set itself to none
when you edit the entry widget from within either the validateCommand
or the invalidCommand
. Such editions will override the one that was being validated.
据推测,这样做是为了避免无限递归。
您可以运行这个(而不是给定的 Tcl 代码,after idle {%W config -validate %v}
)
root.after_idle(lambda: e.config(validate="focusout"))
从回调中安排小部件的重新配置以再次启用验证(在更改您的源之后 e
是正确的 Entry
小部件,即不是第二个)。
问题在标题中,本质上是:如何让 validatecommand
回调在设置条目的 textvariable
后继续被调用?这是最小工作示例 (MWE):
import tkinter as tk
root = tk.Tk()
sv = tk.StringVar()
def callback():
print(sv.get())
sv.set('Set Text.')
return True
e = tk.Entry(root, textvariable=sv, validate="focusout",
validatecommand=callback)
e.grid()
e = tk.Entry(root)
e.grid()
root.mainloop()
请注意,第二个 tk.Entry
小部件可以让第一个小部件失去焦点,这是我们试图捕获的事件。
就像现在的代码一样,当您 运行 它时,您可以更改一次顶部条目小部件的文本。它会正确设置为 Set Text.
然后,如果您尝试再次更改条目的文本,新文本将出现在小部件中,但回调不会发生。
另一方面,如果您注释掉 sv.set('Set Text.')
代码,此行为将完全消失,您可以根据需要多次调用回调。
How can I have the
sv.set()
functionality, while still maintaining the callback getting called every time the Entry widget loses focus?
这在 Tk manual page for entry
中讨论:
The
validate
option will also set itself tonone
when you edit the entry widget from within either thevalidateCommand
or theinvalidCommand
. Such editions will override the one that was being validated.
据推测,这样做是为了避免无限递归。
您可以运行这个(而不是给定的 Tcl 代码,after idle {%W config -validate %v}
)
root.after_idle(lambda: e.config(validate="focusout"))
从回调中安排小部件的重新配置以再次启用验证(在更改您的源之后 e
是正确的 Entry
小部件,即不是第二个)。