¿Cómo vincular los eventos propios en el widget de texto Tkinter después de que se unirá con el widget de texto?

Quiero vincular los eventos Text después de los enlaces de clase de widget de Text , para cambiar el texto del widget cuando se llama a mi función de enlace. Mi enlace, por ejemplo self.text.bind("", self.callback) , se llama antes de que cambie el contenido en el widget Texto.

Lo que sucede en su caso es que su enlace para imprimir el valor ocurre antes del enlace de clase, y es el enlace de clase el que realmente toma la entrada del usuario y lo coloca en el widget. Hay varias formas de resolver este problema. Puede enlazar a lugar de , o puede usar las funciones de validación de entrada incorporadas para que se llame su código cada vez que se presione una tecla. Con esa solución, recibirá todos los datos que necesita: el valor antes del cambio, el valor después del cambio, la tecla que se presionó, etc.

Otra opción es cambiar el orden en que se procesan los eventos. Dado que su pregunta se refiere específicamente a cómo cambiar el orden, eso es lo que abordaré.

Aunque parece que un enlace está asociado con un widget cuando haces algo como entry.bind(...) , en realidad estás asignando un enlace a una “etiqueta de enlace” (o “bindtag”). Por defecto, cada widget tiene una etiqueta de enlace que es igual al nombre del widget. Otros bindtags incluyen la clase de un widget (por ejemplo, “Entrada”), la ruta de la ventana raíz (por ejemplo: “.”) Y la etiqueta especial “todos”. A los widgets se les asigna un conjunto de tags de enlace que se procesan en orden cuando se recibe un evento. El orden predeterminado va de la mayoría a la menos específica: widget, clase, nivel superior, todo.

Hay un par de formas de manipular las tags de unión para obtener el resultado que desea. Una opción es reorganizar el orden de los bindtags. Al mover el bindtag que representa el widget para que esté después del bindtag que representa la clase, la clase manejará el evento antes de pasarlo al widget específico.

Otra opción es agregar un bindtag adicional que esté después del enlace de clase, y luego colocar los enlaces en esta etiqueta en lugar de en la etiqueta que representa el widget.

¿Por qué elegir uno sobre el otro? Al reorganizar el pedido, afectará a todos los enlaces en ese widget. Si tiene muchos enlaces y algunos dependen del orden (de modo que la lata, por ejemplo, no permita ciertas pulsaciones de teclas), cambiar el orden puede hacer que esos enlaces dejen de funcionar.

Al introducir un nuevo bindtag, puede elegir qué enlaces ocurren antes de los enlaces de clase y cuáles suceden después.

En el siguiente código creo tres widgets de entrada. El primero utiliza el conjunto predeterminado de bindtags (establecido explícitamente en el ejemplo, aunque son idénticos al predeterminado). El segundo cambia el orden y el tercero introduce una etiqueta de enlace adicional. Ejecuta el código y luego presiona una tecla mientras el foco está en cada ventana. Tenga en cuenta que en el primer widget de entrada el enlace siempre parece estar detrás de un carácter. Nuevamente, esto se debe a que el enlace del widget ocurre antes de que el enlace de clase ponga el carácter en el widget.

En el segundo y tercer ejemplo, el enlace ocurre después del enlace de clase, de modo que la función ve el cambio en los widgets.

 import Tkinter def OnKeyPress(event): value = event.widget.get() string="value of %s is '%s'" % (event.widget._name, value) status.configure(text=string) root = Tkinter.Tk() entry1 = Tkinter.Entry(root, name="entry1") entry2 = Tkinter.Entry(root, name="entry2") entry3 = Tkinter.Entry(root, name="entry3") # Three different bindtags. The first is just the default but I'm # including it for illustrative purposes. The second reverses the # order of the first two tags. The third introduces a new tag after # the class tag. entry1.bindtags(('.entry1', 'Entry', '.', 'all')) entry2.bindtags(('Entry', '.entry2', '.', 'all')) entry3.bindtags(('.entry3','Entry','post-class-bindings', '.', 'all')) btlabel1 = Tkinter.Label(text="bindtags: %s" % " ".join(entry1.bindtags())) btlabel2 = Tkinter.Label(text="bindtags: %s" % " ".join(entry2.bindtags())) btlabel3 = Tkinter.Label(text="bindtags: %s" % " ".join(entry3.bindtags())) status = Tkinter.Label(anchor="w") entry1.grid(row=0,column=0) btlabel1.grid(row=0,column=1, padx=10, sticky="w") entry2.grid(row=1,column=0) btlabel2.grid(row=1,column=1, padx=10, sticky="w") entry3.grid(row=2,column=0) btlabel3.grid(row=2,column=1, padx=10) status.grid(row=3, columnspan=2, sticky="w") # normally you bind to the widget; in the third case we're binding # to the new bindtag we've created entry1.bind("", OnKeyPress) entry2.bind("", OnKeyPress) entry3.bind_class("post-class-bindings", "", OnKeyPress) root.mainloop()