我如何使Tkinter条目聚焦验证不仅仅是第一次发生



我有一个应用程序,它的一部分将接受用户的输入并将其格式化为标准化的时间格式。要做到这一点,我有一个time输入,它有一个focusout事件绑定到它,调用时间解析器/替换器方法。然而,在测试它并设置消息标签以输出一些东西时,我注意到它只触发一次…

下面是一些示例代码来显示这个问题。

from Tkinter import *
root=Tk()
message_var = StringVar()
message = Label(root, textvariable=message_var, height=2, width=35, bg="light grey")
time_var = StringVar()
time = Entry(root, textvariable=time_var, validate="focusout", validatecommand=time_update)
lose_focus_var = StringVar()
lose_focus_textbox = Entry(root, textvariable=lose_focus_var)
message_var.set("Enter a time below.")
lose_focus_var.set("Click here to lose focus.")
def time_update():
    """
    Updates the time field to show standardized times.
    """
    cur_entry = time_var.get()
    if len(cur_entry) == 0:
        message_var.set("0!")
    elif len(cur_entry) == 1:
        message_var.set("1!")
    elif len(cur_entry) == 2:
       message_var.set("2!")
    elif len(cur_entry) == 3:
       message_var.set("3!")
    elif len(cur_entry) == 4:
       message_var.set("4!")
    elif len(cur_entry) == 5:
       message_var.set("5!")
    else:
       message_var.set("TOO MANY!")
       time_var.set("")
message.pack()
time.pack()
lose_focus_textbox.pack()

要重现我的问题,运行上面的代码。在出现的窗口中,单击空白文本框,输入任意数量的字符,然后单击"单击此处以失去焦点"的文本框。您将看到消息小部件更新正确!耶!

但是,如果您再次单击第一个文本框,更改字符数,然后再次单击"失去焦点"框,则消息将不会再次更新。您将需要关闭窗口并重新运行消息小部件的代码以再次更新。

如果我将time_update调用添加到另一个文本框(并重构time_update以找出哪个文本框调用它),则消息更新将针对每个文本框发生一次。但只有一次。

是否有一种方法可以让我重新触发<FocusOut>事件,而不是破坏条目小部件并重新创建它?为什么不是每次都触发?

一个问题,正如你在你自己的问题的评论中提到的,是你没有返回True或False。验证的全部意义在于让tkinter知道它是否应该允许编辑,并且它基于返回值来执行此操作。

然而,除此之外,主要的问题是您在验证函数中更改了小部件的值。当您这样做时,tkinter将自动禁用验证。有一些变通方法,但是您确实不应该更改验证函数中的值。如果我是一个用户,我会觉得这种行为非常令人沮丧。

如果您想在失去焦点时更改值,请考虑向<FocusOut>添加绑定,而不是使用验证函数。

相关内容

最新更新