Posterior a consultar expertos en el tema, programadores de varias áreas y profesores dimos con la respuesta a la pregunta y la dejamos plasmada en esta publicación.
Sugiero un enfoque más simple. Puede configurar un proxy para el widget, y dentro de ese proxy puede detectar cada vez que se insertó o eliminó algo. Puede usar esa información para generar un evento virtual, que puede vincularse como cualquier otro evento.
Comencemos por crear una clase de widget de texto personalizado, que usará como cualquier otro widget de texto:
import Tkinter as tk
class CustomText(tk.Text):
def __init__(self, *args, **kwargs):
"""A text widget that report on internal widget commands"""
tk.Text.__init__(self, *args, **kwargs)
# create a proxy for the underlying widget
self._orig = self._w + "_orig"
self.tk.call("rename", self._w, self._orig)
self.tk.createcommand(self._w, self._proxy)
def _proxy(self, command, *args):
cmd = (self._orig, command) + args
result = self.tk.call(cmd)
if command in ("insert", "delete", "replace"):
self.event_generate("<>")
return result
El proxy en este ejemplo hace tres cosas:
- Primero llama al comando del widget real, pasando todos los argumentos que recibió.
- A continuación, genera un evento para cada inserción y cada eliminación.
- Luego genera un evento virtual.
- Y finalmente devuelve los resultados del comando de widget real.
Puede usar este widget exactamente como cualquier otro widget de texto, con el beneficio adicional de que puede vincularlo <
.
Por ejemplo, si quisiera mostrar la cantidad de caracteres en el widget de texto, podría hacer algo como esto:
root = tk.Tk()
label = tk.Label(root, anchor="w")
text = CustomText(root, width=40, height=4)
label.pack(side="bottom", fill="x")
text.pack(side="top", fill="both", expand=True)
def onModification(event):
chars = len(event.widget.get("1.0", "end-1c"))
label.configure(text="%s chars" % chars)
text.bind("<>", onModification)
root.mainloop()
Calificaciones y comentarios
Recuerda que puedes mostrar esta división si te ayudó.