0

我正在为 Python/Tkinter 应用程序设计一个“设置”框架,允许用户指定 IP 地址、端口号和其他几个可配置选项。我想在让用户关闭框架以应用它们之前验证用户条目。

根据到目前为止我对Entry小部件validatevalidatecommand选项的阅读(和尝试),他们提供的唯一选择是“重手”验证。在条目有效之前,阻止用户离开条目小部件(或什至键入任何更多击键)的那种。这正是我在设计 GUI 时避免的行为,因为这对用户来说很烦人。

我计划切换到使用 .trace 方法来监视值,并且只禁用“确定/应用”按钮,直到框架中的所有条目都有效。不过,在我这样做之前,我想知道我是否遗漏了有关内置验证选项的任何内容。有没有我错过的不那么严厉的选项?

4

3 回答 3

2

您可以使用验证功能而无需“笨手笨脚”。设置确定/应用按钮的状态后,让您的验证始终返回 True。

于 2012-12-27T14:56:13.197 回答
1

如果你使用跟踪,那么你就拥有了你想要的东西,而根本不需要使用 Tkinter 的验证。使所有跟踪都转到相同的功能,您可以根据需要在其中测试和验证所有值,并根据该功能启用或禁用确定按钮。

于 2012-12-27T13:51:47.003 回答
1

我不确定您是否应该这样做,但是您可以附加一个invalidcommand处理程序,该处理程序将对条目进行操作,就好像一切都很好。

示例脚本:

import Tkinter as tk

def onvalidate(d,i,P,s,S,v,V,W):
    # only lowercase is valid
    valid = (P.lower() == P)
    # set red background if invalid
    newcolor = 'red' if not valid else default_color
    root.nametowidget(W).configure(background=newcolor)
    return valid

def oninvalid(d,i,P,s,S,v,V,W):
    #called if widget is invalid
    widget = root.nametowidget(W)
    # S is the character that *would* have been
    # inserted or deleted, but won't because it is invalid
    # So we do it ourselves
    if S:
        if d=='0':
            widget.delete(i, len(S))
        elif d=='1':
            widget.insert(i, S)
    # Changing the text clears the 'validate' value
    # so we have to reset it
    widget.after_idle(lambda W,v: root.nametowidget(W).configure(validate=v), W, v)

root = tk.Tk()

valhook = (root.register(onvalidate), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
invhook = (root.register(oninvalid), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')

entry = tk.Entry(root, validate="key", validatecommand=valhook, invalidcommand=invhook)

default_color = entry.cget('background')

entry.pack()

root.mainloop()

这将创建一个条目,如果无效则具有红色背景,否则将具有白色背景,但即使条目无效,文本仍将被插入或删除。

于 2012-12-27T17:27:44.773 回答