Cómo pasar un evento al widget padre

¿Es posible en Tkinter pasar un evento directamente al widget principal?

Tengo un canvas que está cubierto por una cuadrícula de otros canvass (¿es el plural?), Que agregué utilizando el método parent_canvas.create_window() . Quiero que algunos de los eventos, por ejemplo, los eventos de liberación del mouse, sean manejados por el canvas principal.

Si solo vinculo el evento a un método primario, las coordenadas event.x y event.y aparecen en relación con el canvas secundario que captura el evento.

Tkinter no pasa eventos a los widgets principales. Sin embargo, puede simular el efecto mediante el uso de tags de enlace (o “bindtags”).

La explicación más breve que puedo dar es la siguiente: cuando agrega enlaces a un widget, no está agregando un enlace a un widget, está enlazando a una “etiqueta de enlace”. Esta etiqueta tiene el mismo nombre que el widget, pero en realidad no es el widget.

Los widgets tienen una lista de tags de enlace, por lo que cuando ocurre un evento en un widget, los enlaces para cada etiqueta se procesan en orden. Normalmente el orden es:

  1. enlaces en el widget real
  2. enlaces en la clase de widget
  3. enlaces en el widget de nivel superior que contiene el widget
  4. enlaces en “todo”

Observe que en ninguna parte de esa lista hay “enlaces en el widget principal”.

Puede insertar sus propias tags en ese orden. Así, por ejemplo, puede agregar el canvas principal a las tags de enlace de cada subcanvas. Cuando te unes a cualquiera de los dos, la función será llamada. Por lo tanto, parecerá que el evento se pasa al padre.

Aquí hay un código de ejemplo escrito en Python 2.7. Si hace clic en un cuadrado gris, verá dos cosas impresas, que muestran que tanto el enlace en el sub-canvas como el enlace en el canvas principal se activan. Si hace clic en un cuadrado rosa, verá que el enlace del sub-canvas se activa, pero evita que se active el enlace principal.

Con eso, todos los clics en los botones se “pasan” al padre. El sub-canvas puede controlar si el padre debe manejar el evento o no, devolviendo “break” si quiere “romper la cadena” del procesamiento del evento.

 import Tkinter as tk class Example(tk.Frame): def __init__(self, parent): tk.Frame.__init__(self, parent) self.main = tk.Canvas(self, width=400, height=400, borderwidth=0, highlightthickness=0, background="bisque") self.main.pack(side="top", fill="both", expand=True) # add a callback for button events on the main canvas self.main.bind("<1>", self.on_main_click) for x in range(10): for y in range(10): canvas = tk.Canvas(self.main, width=48, height=48, borderwidth=1, highlightthickness=0, relief="raised") if ((x+y)%2 == 0): canvas.configure(bg="pink") self.main.create_window(x*50, y*50, anchor="nw", window=canvas) # adjust the bindtags of the sub-canvas to include # the parent canvas bindtags = list(canvas.bindtags()) bindtags.insert(1, self.main) canvas.bindtags(tuple(bindtags)) # add a callback for button events on the inner canvas canvas.bind("<1>", self.on_sub_click) def on_sub_click(self, event): print "sub-canvas binding" if event.widget.cget("background") == "pink": return "break" def on_main_click(self, event): print "main widget binding" if __name__ == "__main__": root = tk.Tk() Example(root).pack (fill="both", expand=True) root.mainloop()