python - 如何在 python tkinter 中验证输入小部件

标签 python user-interface tkinter

我目前正在开发一个基本的计算器程序。我正在尝试使用验证功能,以便用户只能输入 valild_input 列表中的值。包含此列表的 test_input 函数工作正常,直到我决定输入“=”或按 equals 按钮。当我按下equals_button时,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. 验证函数应始终返回 bool 值。

    来自this answer :

    It's important that the validation command returns either True or False. Anything else will cause the validation to be turned off for the widget.

    您的 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
    
  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
    

关于python - 如何在 python tkinter 中验证输入小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52145586/

相关文章:

python - Python 字符串比较_真正_是如何工作的?

当我将脚本作为 Windows 服务运行时,Python 代码无法按预期工作

python - 单击 "play"时如何清除游戏屏幕并移动到新场景

python - 如何重用逻辑来处理 Python 的 tkinter GUI 中的按键和按钮单击?

python - 将类的所有实例存储在类字段中是否不好?

java - Java 中的 GUI,带有用于实例变量的文本区域

java - 当我添加行时,从 AbtractTableModel 扩展的 JTable 不更新 GUI

android - 如何正确设计每侧带有 TextView 的 LinearLayout?

python - Tkinter 多个 Radiobutton 组

python - 关于 tkinter 中绑定(bind)标签的基本查询