Exactamente como dice la pregunta. Los widgets Text
tienen el evento <<Modified>>
, pero los widgets Entry
no parecen funcionar.¿Cómo obtengo una devolución de llamada de evento cuando se modifica un widget de entrada Tkinter?
¿Cómo obtengo una devolución de llamada de evento cuando se modifica un widget de entrada Tkinter?
Respuesta
Agregue un Tkinter StringVar a su widget de Entrada. Enlace su devolución de llamada a StringVar usando el método de rastreo.
from Tkinter import *
def callback(sv):
print sv.get()
root = Tk()
sv = StringVar()
sv.trace("w", lambda name, index, mode, sv=sv: callback(sv))
e = Entry(root, textvariable=sv)
e.pack()
root.mainloop()
Gracias Steven! El Tkinter Folklore de Russell Owen explica cómo obtener el valor de StringVar directamente del argumento de nombre (PY_VAR #) usando globalgetvar(), pero no cómo asignar el nombre a un widget. Su método lambda para cambiar los argumentos de devolución de llamada es como magia (para nosotros los novatos de Python, al menos).
Cuando hay más de una entrada, a menudo es necesario conocer no solo el valor, sino también la entrada que se modificó. Ampliando ligeramente el ejemplo de Steven, el siguiente (Python3) pasa un índice que se puede utilizar para realizar un seguimiento de múltiples entradas.
from tkinter import Tk, Frame, Label, Entry, StringVar
class fruitlist:
def entryupdate(self, sv, i):
print(sv, i, self.fruit[i], sv.get())
def __init__(self, root):
cf = Frame(root)
cf.pack()
self.sva = []
self.fruit = ("Apple", "Banana", "Cherry", "Date")
for f in self.fruit:
i = len(self.sva)
self.sva.append(StringVar())
self.sva[i].trace("w", lambda name, index, mode, var=self.sva[i], i=i:
self.entryupdate(var, i))
Label(cf, text=f).grid(column=2, row=i)
Entry(cf, width=6, textvariable=self.sva[i]).grid(column=4, row=i)
root = Tk()
root.title("EntryUpdate")
app = fruitlist(root)
root.mainloop()
En el momento de escribir (2017, Python 3.6, tkinter versión 8.6.6) los documentos sugieren que .trace
está en desuso. La forma sugerida ahora parece ser:
sv.trace_add("write", callback)
Esto funciona muy bien si desea notificación siempre que se cambie la variable. Sin embargo, mi aplicación solo quiere una notificación cuando el usuario termina de editar el texto. He encontrado que llevan a cuestas en el mecanismo de "validación" para trabajar bien aquí:
from tkinter import *
root = Tk()
sv = StringVar()
def callback():
print(sv.get())
return True
e = Entry(root, textvariable=sv, validate="focusout", validatecommand=callback)
e.grid()
e = Entry(root)
e.grid()
root.mainloop()
Esto invocará callback
cada vez que el widget de entrada pierde el foco (he añadido un widget segunda entrada por lo que el primero uno realmente puede perder el foco!)
conozco otra variante. antes de introducir el código, se podría explicar mejor camino de codificación: Reed aquí http://stupidpythonideas.blogspot.com/2013/12/tkinter-validation.html?view=classic
y no es mi código:
from Tkinter import *
class ttt:
def __init__(self):
self.str1 = StringVar()
self.e1 = Entry(root, textvariable=self.str1)
self.str1.trace('w', self.callback_1)
self.e1.pack()
self.str2 = StringVar()
self.e2 = Entry(root, textvariable=self.str2, state='readonly')
self.e2.pack()
self.str3 = StringVar()
self.e3 = Entry(root, textvariable=self.str3, state='readonly')
self.e3.pack()
bt = Button(root, text = 'ещё', command = self.callback_2)
bt.pack()
def callback_1(self, name='', index='', mode=''):
tmp = self.str1.get()
if tmp:
self.str2.set(int(tmp) * 6)
print self.str2.get()
def callback_2(self, name='', index='', mode=''):
tmp = self.str1.get()
if tmp:
self.str3.set(int(tmp) * 6)
print self.str3.get()
root = Tk()
t = ttt()
root.mainloop()
hay 2 variantes: mediante el botón de prensa y entrar a la entrada ahora puede seleccionar cualquier variante
- 1. tkinter en un widget
- 2. Cómo leer el texto de un texto Tkinter Widget
- 3. ¿Cómo acelerar la devolución de llamada del evento jQuery?
- 4. Android - Necesita devolución de llamada cuando se muestra Vista
- 5. ¿Tiene tkinter un widget de tabla?
- 6. Widget de Notebook en Tkinter
- 7. ¿Cómo llamo a una devolución de llamada JS cuando se completa una carga de archivo?
- 8. Python tkinter Interruptor de estado de widget de entrada a través de botones de radio
- 9. ¿Cómo obtener una devolución de llamada cuando se cierra un cuadro emergente de Spinner?
- 10. ¿Cómo borrar el widget de entrada después de presionar un botón en Tkinter?
- 11. ¿Cómo conectar una variable al widget Entrada?
- 12. Devolución de un evento de una función
- 13. ¿Activar una acción cuando se modifica document.cookie?
- 14. ¿Cómo actualizar la imagen de un widget Tkinter Label?
- 15. ¿Qué hilo ejecuta la devolución de llamada cuando se realiza una llamada de Servicios RIA asíncrona?
- 16. Autofac - devolución de llamada global cuando se resuelve el objeto
- 17. TPL Cómo realizar una 'devolución de llamada'
- 18. devolución de llamada en C#, orden de llamada y devolución
- 19. JQuery UI Autocompletar devolución de llamada
- 20. Cómo resaltar texto en un widget de texto tkinter
- 21. ¿Cómo puedo pasar argumentos al comando de devolución de llamada del botón Tkinter?
- 22. ¿Cómo borrar todo desde el widget de texto tkinter?
- 23. ¿Cómo puede la extensión de Chrome obtener una devolución de llamada cuando se inicia el navegador?
- 24. Tkinter vinculante una función con argumentos a un widget
- 25. ¿Cómo obtener el widget que activó un evento?
- 26. Google Maps API v3 infowindow cerrar evento/devolución de llamada?
- 27. jQuery remove() devolución de llamada?
- 28. Cómo empacar un widget tkinter debajo de un widget existente que se ha empaquetado en el lado izquierdo?
- 29. ¿Hay un evento que se dispara cuando DOM se modifica en MSHTML IE8?
- 30. ¿Cómo puedo vincular una función de devolución de llamada en el evento completo de actualización jstree?
Perfecto, gracias! – bfops
Su solución no parece funcionar con el componente "propio". – Nicholas
@Nicholas: el ejemplo de código funciona tal cual. ¿Qué encuentras que falta? –