Cómo pasar un valor a una entrada validatecommand
Estoy validando un formulario en tkinter usando validatecommand. Hay dos entradas, una solo debe aceptar números enteros y la otra flota.
Aquí está el código básico:
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()
En lugar de escribir dos funciones diferentes para dos tareas muy similares, intenté pasar un número entero al comando de validación (1 para flotante, 2 para entero). Intenté usar lambdas para pasar valores a las funciones de validación, primero en la parte self.register: self.register(lambda: self.val1(1))pero esto dio TypeError: <lambda>() takes 0 positional arguments but 1 was giveny la segunda vez intenté usar lambda en el comando validatecommand: validatecommand = lambda: validCmd1(1)que da TypeError: 'tuple' object is not callable.
¿Es posible pasar valores a un comando de validación?
Respuestas
La validatecommandopción toma una tupla que puede tener los argumentos que desee. Por ejemplo, si desea pasar un número entero, es tan fácil como esto:
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}'")
...
A veces es más fácil de entender si separa el registro del comando del valor pasado a validatecommand. Por ejemplo:
vcmd = self.register(self.val)
...
self.ent1 = tk.Entry(..., validatecommand = (vcmd, 1, "%P"))
self.ent2 = tk.Entry(..., validatecommand = (vcmd, 2, "%P"))