python - 使用 tkinter 条目验证防止用户两次输入相同的值
问题描述
我目前正在开发一个计算器程序。我已经设法使验证代码功能,因此条目小部件只接收来自valid_input
列表的值。虽然,我目前正在尝试阻止诸如“5**2”和“2//2”之类的输入,但有没有办法使用验证码或test_input
函数使用户无法输入两个相同的运算符。这主要是关于除法和乘法运算符。
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)
print(result) #Just for reference
return True
except:
messagebox.showerror("Error", "Math Error", parent = root)
#This function dosen't allow the user to input invalid values
def test_input(value, action):
#list of inputs that is valid for the calculator to function
valid_input = ["7", "8", "9", "+", "4", "5", "6", "-", "1", "2", "3", "*", "0", ".", "/"]
if action == "1": #If an insertion is occuring in the entry
return all(char in valid_input for char in value)
# if action != 1, allow it
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()
解决方案
在验证功能中,您可以拆分插入数字和插入运算符/点的逻辑。
由于您关心条目中已有的内容以及插入字符的位置,因此您应该将更多信息传递给validatecommand
. 您需要的信息是(来自此答案):
# %i = index of char string to be inserted/deleted, or -1
# %s = value of entry prior to editing
# %S = the text string being inserted or deleted, if any
然后,您可以进行多项检查以禁止任何会插入两个运算符或一个接一个的操作:
def test_input(insert, content, index, action):
#list of inputs that is valid for the calculator to function
valid_numbers = ["7", "8", "9", "4", "5", "6", "1", "2", "3", "0"]
valid_chars = ["+", "-", "*", ".", "/"]
index = int(index)
if action != "1": # Always allow if it's not an insert
return True
if insert in valid_numbers: # Always allow a number
return True
if insert in valid_chars: # If it's an operator or point do further checks
if index==0: # Disallow if it's the first character
return False
if content[index-1] in valid_chars: # Disallow if the character before is an operator or point
return False
if index != len(content): # If you're not at the end
if content[index] in valid_chars: # Disallow if the next character is an operator or point
return False
return True # Allow if it's none of the above
else:
return False # Disallow if the character is not a number, operator or point
和
display.configure(validatecommand = (display.register(test_input), "%S", "%s", "%i", "%d"))
我忘记了这会弄乱答案的插入,因为我假设一次只插入一个字符。您可以通过(至少)两种方式解决此问题:
您可以关闭插入答案的验证,并在插入后重新打开:
display.configure(validate='none')
display.insert(0, text)
display.configure(validate='key')
或者,由于答案始终都是数字,因此您可以更改if
验证命令中的第二个以允许多个数字而不是仅一个:
if all(char in valid_numbers for char in insert):
推荐阅读
- python - 提取除第一个单词以外的大写单词的句子
- android - RecyclerView 为空时如何显示空消息?
- python - 如果字典中缺少键,则插入 NaN
- python - 根据数据框中的其他行值添加新列
- python - 一个带条件的线性张量
- visual-studio-code - 具有多个根的 VSCode 工作区
- javascript - 不允许加载本地资源:file:///D
- python - 如何在 selenium python 中排除 timoutexception
- c# - 在webBrowser c#控件中打开网页代替IE控件的问题
- flutter - Flutter 自动填充登录