Comment passer une valeur à une entrée validatecommand

Sep 15 2020

Je valide un formulaire dans tkinter en utilisant validatecommand. Il y a deux entrées, l'une ne doit accepter que des entiers et l'autre des flottants.
Voici le code de base:

import tkinter as tk
class Form(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        validCmd1 = (self.register(self.val1), "%P")
        validCmd2 = (self.register(self.val2), "%P")
        self.lab1 = tk.Label(self, text = "Float:")
        self.lab1.grid(row = 1, column = 0, padx = 10, pady = 10)
        self.ent1 = tk.Entry(self, validate = "key", validatecommand = validCmd1)
        self.ent1.grid(row = 1, column = 1)
        self.lab2 = tk.Label(self, text = "Integer:")
        self.lab2.grid(row = 2, column = 0, padx = 10, pady = (0,10))
        self.ent2 = tk.Entry(self, validate = "key", validatecommand = validCmd2)
        self.ent2.grid(row = 2, column = 1)
    def val1(self, value):
        try:
            float(value)
        except:
            return False
        else:
            return True
    def val2(self, value):
        try:
            int(value)
        except:
            return False
        else:
            return True
app = Form()
app.mainloop()

Au lieu d'écrire deux fonctions différentes pour deux tâches très similaires, j'ai essayé de passer un entier à la commande validate (1 pour float, 2 pour integer). J'ai essayé d'utiliser lambdas pour transmettre des valeurs aux fonctions de validation, d'abord sur la partie self.register: self.register(lambda: self.val1(1))mais cela a donné TypeError: <lambda>() takes 0 positional arguments but 1 was givenet la deuxième fois j'ai essayé d'utiliser lambda sur la commande validatecommand: validatecommand = lambda: validCmd1(1)qui donne TypeError: 'tuple' object is not callable.
Est-il possible de transmettre des valeurs à une commande de validation?

Réponses

1 BryanOakley Sep 15 2020 at 20:31

L' validatecommandoption prend un tuple qui peut avoir tous les arguments souhaités. Par exemple, si vous voulez passer un entier, c'est aussi simple que ceci:

validCmd1 = (self.register(self.val), 1, "%P")
validCmd2 = (self.register(self.val), 2, "%P")

def val(self, arg, value):
    print(f"val1 arg='{arg}' value='{value}'")
    ...

Parfois, il est plus facile de comprendre si vous séparez l'enregistrement de la commande de la valeur transmise à validatecommand. Par exemple:

vcmd = self.register(self.val)
...
self.ent1 = tk.Entry(..., validatecommand = (vcmd, 1, "%P"))
self.ent2 = tk.Entry(..., validatecommand = (vcmd, 2, "%P"))