【发布时间】:2019-06-12 13:47:32
【问题描述】:
我在验证旋转框输入时遇到问题。我有一个似乎可以工作的解决方法;但是,这很尴尬。假设这不是错误,是否有正确的方法来做到这一点?我在 Windows 10 上使用 Anaconda Python 3.6 (tk 8.6)。
问题在于,当旋转框条目中的值介于 to 和 from 之间时,如果从验证函数返回 False,则 validate 设置为 None。这仅在单击向上或向下按钮时发生,而不是在直接编辑文本时发生。
import tkinter as tk
class SpinboxGui:
def __init__(self):
self.root = tk.Tk()
vcmd = (self.root.register(self.validate_spin), '%W', '%P')
self.spin = tk.Spinbox(self.root, from_=0, to=50000)
self.spin.config(validate="key", validatecommand=vcmd)
self.spin.pack()
def validate_spin(self, name, nv):
try:
print(nv)
n = int(nv)
except:
return False
if n <= 15000:
return True
return False
if __name__ == "__main__":
SpinboxGui()
tk.mainloop()
要重现,请突出显示 0 并输入 149999。然后向上单击几次。请注意,验证命令停止被调用。输出是:
01
014
0149
01499
014999
0149999
15000
15001
现在,根据docs,同时使用textVariable 和validateCommand 是危险的;事实上,我拥有crashed Python/Tkinter 的方式不止一种。但是,在这种情况下,您是否使用textVariable 并不重要;问题是一样的。
一种可能的解决方案是在验证函数中编辑to 和from 选项。即使这可行,对我来说也有些问题,因为我正在将旋转框值同步到嵌入式 Matplotlib 图。我需要计算 to 和 from 并为每个 Matplotlib Artist 和 spinbox 转换单位。
由于您无法在验证功能中编辑textVariable,因此我想出的是以下内容。也许有人可以对此进行改进。
def __init__(self):
# http://stackoverflow.com/a/4140988/675216
vcmd= (self.root.register(self.validate_spin), '%W', '%P')
# Rest of code left out
self.spin.config(validate="key", validatecommand=vcmd)
self.spin.bind("<<ResetValidate>>", self.on_reset_validate)
def on_reset_validate(self, event):
# Turn validate back on and set textVariable
self.spin.config(validate="key")
def validate_spin(self, name, nv):
# Do validation ...
if not valid:
self.spin.event_generate("<<ResetValidate>>", when="tail")
return valid
【问题讨论】:
-
此语句为假:"问题是如果您从验证函数返回 False,则 validate 设置为 None..." - 不会设置验证函数到
None只是因为你返回False。事实上,唯一有效的返回值是True和False。请阅读并遵循此处的建议:How to create a Minimal, Complete, and Verifiable example -
重现问题需要花费大量时间和精力。不是我懒得做;我认为这可能是旋转框的预期行为。我不想花时间去寻找一个不存在的问题。但现在我知道了,就在这里。