我正在使用 validatecommand
“动态地”观察和验证条目小部件的输入。
validatecommand
的标准用法防止将无效字符输入到观察到的条目小部件中。这不是我喜欢的行为,所以我使用了 validatecommand
将条目小部件的字符串传递给另一个函数和return True
任何状况之下。 floatstr_to_float
使用名为 preg
的正则表达式验证字符串.
如果正则表达式匹配输入有效,则一切正常,因此 print('approved')
被执行。然而,如果用户输入了无效的输入,则正则表达式不匹配,print('not approved')
被执行,相应的条目小部件应填充为红色(颜色更改尚未正确实现)。
到目前为止,我所做的是使用 <widget>.config(bg=<background>)
更改第一个条目小部件的背景。通过索引所有已创建条目小部件的列表来检查我是否能够访问每个小部件。
validatecommand
可以通过几个arguments执行的函数(例如输入/文本字符串和小部件/窗口路径名)。因此,获取对无效小部件的引用通常不是问题。但是,validatecommand
传递的路径名似乎不是 python 可访问的。如何从此路径名获取引用(例如唯一变量名)以通过执行 <widget>.config(bg=<background>)
更改背景在包含(无效)有效输入的小部件上?
-- MWE--
#!/usr/bin/env python3
# -*- coding: <utf-8> -*-
# code adapted from:
# http://stackoverflow.com/questions/4140437/python-tkinter-interactively-validating-entry-widget-content
import tkinter as tk
import re
class MyApp():
def __init__(self):
self.root = tk.Tk()
self.parameternames = [
('a', 'U'), ('b', 'U'), ('c', 'U'), ('d', 'U'), ('e', 'U'),
('f', 'U'), ('g', 'U'), ('h', 'U'), ('i', 'U'), ('j', 'U'),
('k', 'U'), ('l', 'U'), ('m', 'U'), ('n', 'U'), ('o', 'U'),
('p', 'U'), ('q', 'U'), ('r', 'U'), ('s', 'U'), ('t', 'U')]
self.vcmd = (self.root.register(self.OnValidate), '%P', '%W')
self.create_widgets()
def create_widgets(self):
self.entries = []
for i in enumerate(self.parameternames):
entry = tk.Entry(self.root, validate="all", validatecommand=self.vcmd)
self.default_bg = entry.cget("bg")
entry.pack()
self.entries.append(entry)
self.root.mainloop()
def OnValidate(self, P, W):
# %P = value of the entry if the edit is allowed
# %W = the tk name of the widget (pathname)
print("OnValidate:")
print("P='%s'" % P )
print("W='%s'" % W )
self.floatstr_to_float(P, W)
# return True to display inserted character, validation is done by a re in 'floatstr_to_float()'
return True
def floatstr_to_float(self, fs, W):
preg = re.compile('^\s*(?P<int>\d*)\s*[\.,]?\s*(?P<dec>\d*)\s*$')
m = preg.match(fs)
if m:
print('approved')
intprt=m.group('int')
frcprt=m.group('dec')
f = 0. if (intprt == '' and frcprt == '') else float('%s.%s' %(intprt, frcprt)) # not needed yet
# currently: just changing the color of the first entry widget (proof of concept)
# aim: pass unique name of edited entry widget to self.change_bg() for changing bg of
# appropriate entry widget
self.change_bg(self.entries[0], 1)
else:
print('not approved')
# see comment in if-statement above
self.change_bg(self.entries[0], 0)
def change_bg(self, name, approved):
if approved == 1:
name.config(bg=self.default_bg)
else:
name.config(bg='#d9534f')
app=MyApp()
最佳答案
您可以使用Tk
的nametowidget
方法。这会根据其名称找到小部件。所以使用:
self.change_bg(self.root.nametowidget(W), 1)
关于python - 通过 Tk 小部件/窗口路径名访问小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27274172/