Python 限制Tkinter条目小部件中的值
我需要将Entry小部件中的值限制为仅数字。我实施的方式是:Python 限制Tkinter条目小部件中的值,python,tkinter,validation,Python,Tkinter,Validation,我需要将Entry小部件中的值限制为仅数字。我实施的方式是: import numpy as np from Tkinter import *; import tkMessageBox; class window2: def __init__(self,master1): self.panel2=Frame(master1) self.panel2.grid() self.button2=Button(self.panel2,tex
import numpy as np
from Tkinter import *;
import tkMessageBox;
class window2:
def __init__(self,master1):
self.panel2=Frame(master1)
self.panel2.grid()
self.button2=Button(self.panel2,text="Quit",command=self.panel2.quit)
self.button2.grid()
self.text1=Entry(self.panel2)
self.text1.grid()
self.text1.bind('<KeyPress>', self.keybind1)
self.text1.focus()
def keybind1 (self,event):
if event.int in np.linspace(0,9,10):
print event.int
root1=Tk()
window2(root1)
root1.mainloop()
将numpy导入为np
来自Tkinter进口*;
导入tkMessageBox;
第2类:
定义初始化(自,主1):
self.panel2=框架(master1)
self.panel2.grid()
self.button2=按钮(self.panel2,text=“Quit”,command=self.panel2.Quit)
self.button2.grid()
self.text1=条目(self.panel2)
self.text1.grid()
self.text1.bind(“”,self.keybind1)
self.text1.focus()
def keybind1(自身,事件):
如果np.linspace(0,9,10)中的event.int:
打印事件.int
root1=Tk()
窗口2(root1)
root1.mainloop()
我不断收到错误消息,事件实例没有属性“int”。我该怎么办 这使用
validatecommand
将tk.Entry
中的有效用户输入限制为可解释为浮动的字符串:
import tkinter as tk
class window2:
def __init__(self, master1):
self.panel2 = tk.Frame(master1)
self.panel2.grid()
self.button2 = tk.Button(self.panel2, text = "Quit", command = self.panel2.quit)
self.button2.grid()
vcmd = (master1.register(self.validate),
'%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
self.text1 = tk.Entry(self.panel2, validate = 'key', validatecommand = vcmd)
self.text1.grid()
self.text1.focus()
def validate(self, action, index, value_if_allowed,
prior_value, text, validation_type, trigger_type, widget_name):
if value_if_allowed:
try:
float(value_if_allowed)
return True
except ValueError:
return False
else:
return False
root1 = tk.Tk()
window2(root1)
root1.mainloop()
参考资料:
- 说明了
和validate
选项。(感谢您的链接)validatecommand
- 我学会了如何用Python实现这一点
- 答案几乎完美,只需添加一点内容即可删除整个字符串。
只有在插入文本时才应检查浮动
def validate_float(self, action, index, value_if_allowed,
prior_value, text, validation_type, trigger_type, widget_name):
# action=1 -> insert
if(action=='1'):
if text in '0123456789.-+':
try:
float(value_if_allowed)
return True
except ValueError:
return False
else:
return False
else:
return True
我还必须处理一个初始插入案例。这就是我的结局:
def _checkNumberOnly(self, action, value_if_allowed):
if action != '1':
return True
try:
return value_if_allowed.isnumeric()
except ValueError:
return False
vcmd = (self.register(self._checkNumberOnly), '%d', '%P')
self.port = ttk.Entry(self, width=35, validate='key', validatecommand=vcmd)
因此,它验证以下各项:
self.port.insert(0, '6379')
我不确定是否需要catch,因为
isnumeric()
不声明它会引发异常。我不熟悉python和Tkinker,但这对我来说最合适:
def keybind1 (self,event):
v = event.char
try:
v = int(v)
except ValueError:
if v!="\x08" and v!="":
return "break"
v=int(v)
在除数字键以外的任何键上触发ValueError
,但是
如果v=“\x08和
v!=”:“
语句仍然允许使用backspace、(“\x08”)
和delete、arrow、home、end等键,(这些键具有的event.char
”,”,要正常工作-否则,break
命令会停止在entry小部件中输入其他字符。我意识到回答这个问题已经很晚了,但我觉得我可以给出更简单的答案。。。一旦你了解了它的工作原理,它就非常简单了
使用条目
小部件附带的验证功能
让我们假设self
是一个小部件:
vcmd = (self.register(self.callback))
w = Entry(self, validate='all', validatecommand=(vcmd, '%P'))
w.pack()
def callback(self, P):
if str.isdigit(P) or P == "":
return True
else:
return False
您不需要包括所有的替换代码:(“%d”、“i”、“p”、“s”、“s”、“v”、“v”、“W”)
),只需要您将使用的代码
条目
小部件返回一个字符串,因此您必须以某种方式提取任何数字,以便将它们与其他字符分开。最简单的方法是使用str.isdigit()
。这是一个内置在python库中的方便的小工具,不需要额外的导入,它将识别从条目
小部件返回的字符串中找到的任何数字(数字)
if语句的或p==”
部分允许您删除整个条目,如果没有它,您将无法删除最后一位(条目框中的第一位),因为'%p'
返回空值并导致回调返回False
。我不会在这里详细说明原因
validate='all'
允许回调在您focusin
、focusout
或在任何键上计算p
的值,从而更改小部件中的内容,因此您不会为误入的字符留下任何漏洞
总之,让事情变得简单。如果您的回调返回True
,它将允许输入数据。如果回调返回'False',它将基本上'忽略'键盘输入
看看这两个参考资料。它们解释了每个替换代码的含义以及如何实现它们
编辑:
这将只考虑盒子中允许的内容。但是,您可以在回调函数中,将P
所具有的任何值添加到所需的任何变量中。如果您处理的是以逗号作为小数点的区域设置:
locale.setlocale(locale.LC_ALL,'de_DE.UTF-8') # German
显然,事件对象没有int
属性。谁说的?我试着按照我看不到在这个问题上提到的int
…关于验证的Tk文档可能会有所帮助:感谢链接,schlenk。如何处理删除输入字段中的所有字符?我尝试了如果action==0:returntrue
,但没有成功。但是,如果我在之后选中if value\u if_allowed=='':return True
,除了ValueError:
,它确实允许我删除字段的内容。奇怪。为什么退格删除所有输入的数据在这里不起作用。一个值始终存在,即使在键入值后按backspace键@sunny_old_days:谢谢你的bug报告<当value\u if\u allowed
等于空字符串时,code>float(value\u if\u allowed)
正在引发ValueError
。我更改了代码以避免出现此ValueError
,从而允许使用空字符串。感谢您对unutbu答案的修复!他留下了你提到的那种散漫的性格。这是最好的解决办法。谢谢我更喜欢这一个,代码行少一些,所以在我看来更容易理解,谢谢。
vcmd = (self.root.register(self.entry_numericonly), '%d', '%P')
self.my_float_entry = tk.Entry(self.root, ... , validate='key', validatecommand=vcmd)
def entry_numericonly(self, action, value_if_allowed):
if(action == "1"):
try:
loc_float = locale.atof(value_if_allowed)
loc_float_format = locale.format("%f", loc_float)
try:
loc_same_length = loc_float_format[:len(value_if_allowed)]
return value_if_allowed == loc_same_length
except:
return False
except:
return False
else:
return True