Pregunta
Jugando con Python - tkInter - widget de entrada - cuando uso validatecommand (abajo), la verificación ocurre la primera vez que la cadena > Max, pero cuando continúo ingresando texto los pasos de verificación: ¿no hay eliminación o inserción después de la primera vez? ¿Algún consejo? (fuera de no construir una aplicación de escritorio a través de Python)
#!/usr/bin/env python
from Tkinter import *
class MyEntry(Entry):
def __init__(self, master, maxchars):
Entry.__init__(self, master, validate = "key", validatecommand=self.validatecommand)
self.MAX = maxchars
def validatecommand(self, *args):
if len(self.get()) >= self.MAX:
self.delete(0,3)
self.insert(0, "no")
return True
if __name__ == '__main__':
tkmain = Tk()
e = MyEntry(tkmain, 5)
e.grid()
tkmain.mainloop()
Solución
La opción de validación también se establecerá en none cuando edite el widget de entrada desde validateCommand o invalidCommand. Dichas ediciones anularán la que se estaba validando. Si desea editar el widget de entrada (por ejemplo, configúrelo en {}) durante la validación y aún tenga configurada la opción de validación, debe incluir el comando
después de inactivo {% W config -validate% v}
no sé cómo traducir eso a Python.
Otros consejos
Aquí hay una muestra de código que limitará la entrada a 5 caracteres:
import Tkinter as tk
master = tk.Tk()
def callback():
print e.get()
def val(i):
print "validating"
print i
if int(i) > 4:
print "False"
return False
return True
vcmd = (master.register(val), '%i')
e = tk.Entry(master, validate="key", validatecommand=vcmd)
e.pack()
b = tk.Button(master, text="OK", command=lambda: callback())
b.pack()
tk.mainloop()
Agregué un montón de declaraciones impresas para que puedas ver lo que está haciendo en la consola.
Estas son las otras sustituciones que puede pasar:
%d Type of action: 1 for insert, 0 for delete, or -1 for focus,
forced or textvariable validation.
%i Index of char string to be inserted/deleted, if any, otherwise -1.
%P The value of the entry if the edit is allowed. If you are config-
uring the entry widget to have a new textvariable, this will be
the value of that textvariable.
%s The current value of entry prior to editing.
%S The text string being inserted/deleted, if any, {} otherwise.
%v The type of validation currently set.
%V The type of validation that triggered the callback (key, focusin,
focusout, forced).
%W The name of the entry widget.
Estoy seguro de cuál es exactamente la razón, pero tengo una corazonada. La verificación de validación se realiza cada vez que se edita la entrada. Hice algunas pruebas y descubrí que efectivamente se ejecuta, y puede hacer todo tipo de cosas durante la validación cada vez. Lo que hace que deje de funcionar correctamente es cuando lo edita desde la función validatecommand. Esto hace que deje de llamar a la función de validación más. Supongo que ya no reconoce más ediciones en el valor de entrada o algo así.
lgal Serban parece tener la información detrás de escena de por qué ocurre esto.