繁体   English   中英

如何验证python tkinter中的条目小部件

[英]How to validate entry widgets in python tkinter

我目前正在研究一个基本的计算器程序。 我正在尝试使用validate函数,因此用户只能输入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()

您的代码有2个问题。

  1. 验证函数应始终返回布尔值。

    这个答案

    验证命令返回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! 

    这就是在程序从Entry中删除文本后禁用验证的原因。 修复很简单:返回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 
  2. 验证功能需要处理多字符输入。

    您假设为输入的每个字符调用验证函数。 当用户使用键盘键入公式时,情况就是如此,但在复制/粘贴或使用.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 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM