Tkinter validatecommand 命令破坏参数类型?

时间:2021-03-07 01:02:30

标签: python validation tkinter user-input tkinter-entry

我一直在尝试通过附加一个处理函数来在 Entry 小部件中进行一些类型检查,该处理函数提供了条目和预期类型(来自内置 type() 函数的 Type 类对象)。一切都很好,只是似乎 validatecommand 将 Type 对象的类型从 Type 更改为字符串,这并非不可逾越,但让我很好奇发生了什么。

请参阅下面的最小可重现示例 - 请注意,处理程序在本机 python 中正确传递了类型对象,但使用 tkinter,类型对象的类型更改为字符串。

#NATIVE PYTHON

variable = 'HelloWorld'
vartype = type(variable)

print('VALUE OF VARTYPE: ', vartype, 'TYPE OF VARTYPE: ', type(vartype))

def handler(variable,vartype):
    print('VALUE OF VARTYPE: ', vartype, 'TYPE OF VARTYPE: ', type(vartype))

handler(variable,vartype)

#TKINTER VALIDATE HANDLER

import tkinter as tk

top = tk.Tk()
frame = tk.Frame(top)
frame.pack()
vcmd =frame.register(handler)
entry = tk.Entry(frame, validate = 'focusout', validatecommand = (vcmd,"%P",vartype))
entry.pack()

top.mainloop()

解决这个问题的方法是为处理程序制作一个 lambda 包装器,以避免将类型对象传递给 validatecommand:


#NATIVE PYTHON

variable = 'HelloWorld'
vartype = type(variable)


print('VALUE OF VARTYPE: ', vartype, 'TYPE OF VARTYPE: ', type(vartype))

def handler(*variable,vartype=vartype):
    print('VALUE OF VARTYPE: ', vartype, 'TYPE OF VARTYPE: ', type(vartype))

handler(*variable,vartype=vartype)

#TKINTER VALIDATE HANDLER

import tkinter as tk

top = tk.Tk()
frame = tk.Frame(top)
frame.pack()
vcmd =frame.register(lambda *args, vartype=vartype : handler(*args,vartype=vartype))
entry = tk.Entry(frame, validate = 'focusout', validatecommand = (vcmd,"%P"))
entry.pack()

top.mainloop()

然而,我仍然有些不满意,不知道第一次迭代发生了什么 - 我在那里做错了什么?

1 个答案:

答案 0 :(得分:2)

<块引用>

一切都很好,只是似乎validatecommand将Type对象的类型从Type更改为字符串,这并非不可逾越,但让我很好奇发生了什么......但是,我仍然有些不满意,不知道是什么第一次迭代发生了 - 我在那里做错了什么?

你没有做错任何事,只是试图做一些设计 tkinter 不支持的事情。

Tkinter 是一个围绕嵌入式 Tcl 解释器的面向对象的包装器。这个嵌入式解释器对 python 对象一无所知,因此无法将 python 对象传递到 Tcl 解释器中或从 Tcl 解释器中检索。当你将一个 python 函数作为参数传递时,tkinter 必须将它转换成一个字符串,然后它才能被 Tcl 解释器处理。

这就是您必须向 Tcl 解释器注册 Python 函数的原因。 Tkinter 将创建一个内部 Tcl 函数,该函数知道如何调用您的 Python 函数。然后可以在 Tcl 解释器内部使用该函数的名称。