在 tkinter 中交互式验证 Entry 小部件内容(第 2 部分 - 更改 entry 对象的属性)
Interactively validating Entry widget content in tkinter (part 2 - change the properties of the entry object)
我正在尝试使用此处答案中的验证程序:Interactively validating Entry widget content in tkinter
我想通过检查输入类型来更改背景颜色。不幸的是,我无法将入口指针传递给验证函数:vcmd = (self.register(self.onValidate), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
。因此,我尝试了这个:
self.entry = tk.Entry(self, validate="all")
self.entry['validatecommand'] = self.onValidate2(self.entry)
但这只有效一次。您能否解释一下访问调用验证函数(或其他函数)的对象的最佳方法是什么,以及为什么我的 validatecommand
用法只能使用一次?
这是上面 link 的完整代码,并进行了一些更正:
import tkinter as tk # python 3.x
# import Tkinter as tk # python 2.x
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
# valid percent substitutions (from the Tk entry man page)
# note: you only have to register the ones you need; this
# example registers them all for illustrative purposes
#
# %d = Type of action (1=insert, 0=delete, -1 for others)
# %i = index of char string to be inserted/deleted, or -1
# %P = value of the entry if the edit is allowed
# %s = value of entry prior to editing
# %S = the text string being inserted or deleted, if any
# %v = the type of validation that is currently set
# %V = the type of validation that triggered the callback
# (key, focusin, focusout, forced)
# %W = the tk name of the widget
vcmd = (self.register(self.onValidate),
'%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
# self.entry = tk.Entry(self, validate="key", validatecommand=vcmd)
self.entry = tk.Entry(self, validate="all")
# self.entry['validatecommand'] = vcmd
self.entry['validatecommand'] = self.onValidate2(self.entry)
self.text = tk.Text(self, height=10, width=40)
self.entry.pack(side="top", fill="x")
self.text.pack(side="bottom", fill="both", expand=True)
def onValidate(self, d, i, P, s, S, v, V, W):
self.text.delete("1.0", "end")
self.text.insert("end","OnValidate:\n")
self.text.insert("end","d='%s'\n" % d)
self.text.insert("end","i='%s'\n" % i)
self.text.insert("end","P='%s'\n" % P)
self.text.insert("end","s='%s'\n" % s)
self.text.insert("end","S='%s'\n" % S)
self.text.insert("end","v='%s'\n" % v)
self.text.insert("end","V='%s'\n" % V)
self.text.insert("end","W='%s'\n" % W)
self.text.insert("end","W='%s'\n" % W)
W.config({"background": "Red"})
# Disallow anything but lowercase letters
if S == S.lower():
return True
else:
self.bell()
return False
def onValidate2(self, entry):
try:
entry.config({"background": "White"})
value = int(entry.get())
print("Int Value=",value)
# return int(value)
except ValueError:
entry.config({"background": "Red"})
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
I can't pass the entry pointer to the validation function
您可以传递入口小部件的名称,并使用 tkinter 的 nametowidget
方法将该名称转换为小部件的实例。
Could you please explain ... why my validatecommand usage only works once?
您没有正确配置验证命令。考虑这段代码:
self.entry['validatecommand'] = self.onValidate2(self.entry)
以上代码在功能上与此相同:
result = self.onValidate2(self.entry)
self.entry['validatecommand'] = result
换句话说,您立即 调用验证函数,然后将 validatecommand
选项设置为 None
。 validationcommand
选项必须设置为 callable。
这是您要实现的目标的工作示例。通常 validate 命令必须 return True
有效条目和 False
无效条目,但我猜你实际上想要允许无效条目而只是想打开背景红色.
此示例创建了多个条目小部件,因此您可以看到通过将小部件的名称传递给验证函数,单个验证函数适用于多个小部件。
import tkinter as tk
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
vcmd = self.register(self.onValidate)
for i in range(4):
entry = tk.Entry(self, validate="all")
entry.configure(validatecommand=(vcmd, "%W", "%P"))
entry.pack(side="top", fill="x")
def onValidate(self, entry_name, new_value):
entry = self.nametowidget(entry_name)
entry.configure(background="white")
try:
int(new_value)
except ValueError:
entry.configure(background="red")
return True
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
我正在尝试使用此处答案中的验证程序:Interactively validating Entry widget content in tkinter
我想通过检查输入类型来更改背景颜色。不幸的是,我无法将入口指针传递给验证函数:vcmd = (self.register(self.onValidate), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
。因此,我尝试了这个:
self.entry = tk.Entry(self, validate="all")
self.entry['validatecommand'] = self.onValidate2(self.entry)
但这只有效一次。您能否解释一下访问调用验证函数(或其他函数)的对象的最佳方法是什么,以及为什么我的 validatecommand
用法只能使用一次?
这是上面 link 的完整代码,并进行了一些更正:
import tkinter as tk # python 3.x
# import Tkinter as tk # python 2.x
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
# valid percent substitutions (from the Tk entry man page)
# note: you only have to register the ones you need; this
# example registers them all for illustrative purposes
#
# %d = Type of action (1=insert, 0=delete, -1 for others)
# %i = index of char string to be inserted/deleted, or -1
# %P = value of the entry if the edit is allowed
# %s = value of entry prior to editing
# %S = the text string being inserted or deleted, if any
# %v = the type of validation that is currently set
# %V = the type of validation that triggered the callback
# (key, focusin, focusout, forced)
# %W = the tk name of the widget
vcmd = (self.register(self.onValidate),
'%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
# self.entry = tk.Entry(self, validate="key", validatecommand=vcmd)
self.entry = tk.Entry(self, validate="all")
# self.entry['validatecommand'] = vcmd
self.entry['validatecommand'] = self.onValidate2(self.entry)
self.text = tk.Text(self, height=10, width=40)
self.entry.pack(side="top", fill="x")
self.text.pack(side="bottom", fill="both", expand=True)
def onValidate(self, d, i, P, s, S, v, V, W):
self.text.delete("1.0", "end")
self.text.insert("end","OnValidate:\n")
self.text.insert("end","d='%s'\n" % d)
self.text.insert("end","i='%s'\n" % i)
self.text.insert("end","P='%s'\n" % P)
self.text.insert("end","s='%s'\n" % s)
self.text.insert("end","S='%s'\n" % S)
self.text.insert("end","v='%s'\n" % v)
self.text.insert("end","V='%s'\n" % V)
self.text.insert("end","W='%s'\n" % W)
self.text.insert("end","W='%s'\n" % W)
W.config({"background": "Red"})
# Disallow anything but lowercase letters
if S == S.lower():
return True
else:
self.bell()
return False
def onValidate2(self, entry):
try:
entry.config({"background": "White"})
value = int(entry.get())
print("Int Value=",value)
# return int(value)
except ValueError:
entry.config({"background": "Red"})
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
I can't pass the entry pointer to the validation function
您可以传递入口小部件的名称,并使用 tkinter 的 nametowidget
方法将该名称转换为小部件的实例。
Could you please explain ... why my validatecommand usage only works once?
您没有正确配置验证命令。考虑这段代码:
self.entry['validatecommand'] = self.onValidate2(self.entry)
以上代码在功能上与此相同:
result = self.onValidate2(self.entry)
self.entry['validatecommand'] = result
换句话说,您立即 调用验证函数,然后将 validatecommand
选项设置为 None
。 validationcommand
选项必须设置为 callable。
这是您要实现的目标的工作示例。通常 validate 命令必须 return True
有效条目和 False
无效条目,但我猜你实际上想要允许无效条目而只是想打开背景红色.
此示例创建了多个条目小部件,因此您可以看到通过将小部件的名称传递给验证函数,单个验证函数适用于多个小部件。
import tkinter as tk
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
vcmd = self.register(self.onValidate)
for i in range(4):
entry = tk.Entry(self, validate="all")
entry.configure(validatecommand=(vcmd, "%W", "%P"))
entry.pack(side="top", fill="x")
def onValidate(self, entry_name, new_value):
entry = self.nametowidget(entry_name)
entry.configure(background="white")
try:
int(new_value)
except ValueError:
entry.configure(background="red")
return True
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()