【问题标题】:Calling tk.StringVar.set() on a tk.Entry textvariable causes validate="focusout" to stop getting called在 tk.Entry 文本变量上调用 tk.StringVar.set() 会导致 validate="focusout" 停止被调用
【发布时间】:2018-09-29 19:36:10
【问题描述】:

问题在标题中,本质上是:在设置条目的textvariable 后,如何让validatecommand 回调继续被调用?这是最低工作示例 (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 小部件的存在是为了让第一个小部件失去焦点,这是我们试图捕捉的事件。

就像现在的代码一样,当您运行它时,您可以一次更改顶部 Entry 小部件的文本。它将正确设置为Set Text. 然后,如果您尝试再次更改条目的文本,新文本将在小部件中,但不会发生回调。

另一方面,如果您注释掉 sv.set('Set Text.') 代码,此行为将完全消失,并且回调会被调用多次。

我怎样才能拥有sv.set() 功能,同时在每次Entry 小部件失去焦点时仍保持回调被调用?

【问题讨论】:

    标签: python python-3.x tkinter callback tkinter-entry


    【解决方案1】:

    这在Tk manual page for entry中讨论:

    当您从validateCommandinvalidCommand 中编辑条目小部件时,validate 选项也会将其自身设置为none。此类版本将覆盖正在验证的版本。

    大概是为了避免无限递归。

    你可以运行它(而不是给定的 Tcl 代码,after idle {%W config -validate %v}

    root.after_idle(lambda: e.config(validate="focusout"))
    

    从回调安排重新配置小部件以再次启用验证(在更改您的源以便 e 是正确的 Entry 小部件之后,即不是第二个小部件)。

    【讨论】:

    • 完美!正是我需要的。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2015-07-17
    • 1970-01-01
    • 2021-06-18
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    • 2012-12-20
    • 1970-01-01
    相关资源
    最近更新 更多