python - 如何在 python tkinter 中验证条目小部件
问题描述
我目前正在开发一个基本的计算器程序。我正在尝试使用验证功能,因此用户只能从valild_input
列表中输入值。包含此列表的test_input
函数可以正常工作,直到我决定输入“=”或按equals button
. 当我按下条目equals_button
上的当前方程式时,display
不会删除并替换为结果。虽然当我按下键盘上的“=”键时不会发生这种情况。唯一的问题是等号停留在 上display
,之后,条目小部件完全停止验证用户的输入。
from tkinter import *
from tkinter import messagebox
def replace_text(text):
display.delete(0, END)
display.insert(0, text)
#Calculates the input in the display
def calculate(event = None):
equation = display.get()
try:
result = eval(equation)
replace_text(result)
except:
messagebox.showerror("Error", "Math Error", parent = root)
def test_input(value, action):
valid_input = ["7", "8", "9", "+", "4", "5", "6", "-", "1", "2", "3", "*", "0", ".", "/"]
if action == "1":
if value not in valid_input:
return False
return True
root = Tk()
root.title("Calculator testing")
display = Entry(root, font=("Helvetica", 16), justify = "right", validate = "key")
display.configure(validatecommand = (display.register(test_input), "%S", "%d"))
display.insert(0, "")
display.grid(column = 0, row = 0, columnspan = 4, sticky = "NSWE", padx = 10, pady = 10)
display.bind("=", calculate)
#Equals button
button_equal = Button(root, font = ("Helvetica", 14), text = "=", command =
calculate, bg = "#c0ded9")
button_equal.grid(column = 2, row = 1, columnspan = 2, sticky = "WE")
#All clear button
button_clear = Button(root, font = ("Helvetica", 14), text = "AC", command = lambda: replace_text(""), bg = "#c0ded9")
button_clear.grid(column = 0, row = 1, columnspan = 2, sticky = "WE")
#Main Program
root.mainloop()
解决方案
您的代码有两个问题。
验证函数应该总是返回一个布尔值。
从这个答案:
验证命令返回 True 或 False 很重要。其他任何事情都会导致小部件的验证被关闭。
您的
test_input
函数没有这样做 - 它有一个返回的分支None
。def test_input(value, action): valid_input = ["7", "8", "9", "+", "4", "5", "6", "-", "1", "2", "3", "*", "0", ".", "/"] if action == "1": if value not in valid_input: return False return True # None is being returned here!
这就是为什么在您的程序从条目中删除文本后禁用验证的原因。修复很简单:返回
True
而不是None
.def test_input(value, action): valid_input = ["7", "8", "9", "+", "4", "5", "6", "-", "1", "2", "3", "*", "0", ".", "/"] if action == "1": if value not in valid_input: return False return True # if action != 1, allow it return True
验证功能需要处理多字符输入。
您已经假设对输入的每个字符都调用了验证函数。当用户使用键盘键入公式时,这是正确的,但在复制/粘贴或使用
.insert(...)
. 您的函数需要处理这些情况。def test_input(value, action): valid_input = ["7", "8", "9", "+", "4", "5", "6", "-", "1", "2", "3", "*", "0", ".", "/"] if action == "1": return all(char in valid_input for char in value) # if action != 1, allow it return True
推荐阅读
- flutter - 如何自定义屏幕中间的滑块
- python - 我如何过滤从 1 到 101 的列表中的多个可分数字?
- node.js - node.js、socket.io、nginx-proxy一起使用,连续调用io.on('connection')
- python - 在 for 循环参数中使用变量值
- netlogo - 行人环境:海龟不识别补丁类型和周围环境
- python - 为什么我在 seaborn jointplot 函数中出现此类型错误?
- android - Android从aar中排除jar,appcompat-1.2.0.aar中有classes.jar和lint.jar
- vue.js - 如何通过 Antd 和 VueJS 在表格单元格中使用 customRender
- payment - BigCommerce 是否支持 DigitalRiver 付款方式?
- anchor - 是否可以在 onchange(); 期间更改锚链接?