2013-01-23 9 views
5

Ich habe einige Code wie diesesWie kann ich das Ereignis in Tkinter stoppen?

from Tkinter import * 
master = Tk() 
def oval_mouse_click(event): 
    print "in oval" 
def canvas_mouse_click(event): 
    print "in canvas" 
w = Canvas(master, width = 800, height = 600) 
uid = w.create_oval(390, 290, 410, 310, fill='blue') 
w.tag_bind(uid, "<Button-1>", lambda x: oval_mouse_click(x)) 
w.bind("<Button-1>" , canvas_mouse_click) 
w.pack() 
mainloop() 

Wenn ich auf Leinwand klicken Ich habe „in Leinwand“ Nachricht in der Konsole. Wenn ich auf Oval klicke] habe ich zwei Nachrichten "in Oval" und "in Canvas", aber ich möchte nur die erste Nachricht haben. Gibt es eine Möglichkeit, die Ereigniserhöhung zu stoppen?

Ich kann diese Aufgabe mit einigen globalen Flagge tun, aber ich denke, es sollte mehr natürliche Weise für Tkl.

+1

Sie haben den einfachsten Weg gefunden, 'return 'break'' funktioniert nicht für Canvas-Tag-Bind. – mmgp

+0

Zugehörig: [Python tkinter: Stoppen der Ereignisausbreitung in Textwidget-Tags] (http://stackoverflow.com/questions/13066773/python-tkinter-stopping-event-propagation-in-text-widgets-tags/13076458) – phoibos

Antwort

2

Hier ist das einfachste Beispiel um Ihr Problem zu umgehen:

import Tkinter 

def oval_mouse_click(event): 
    print "in oval" 
    event.widget.tag_click = True 

def canvas_mouse_click(event): 
    if event.widget.tag_click: 
     event.widget.tag_click = False 
     return 
    print "in canvas" 

root = Tkinter.Tk() 
canvas = Tkinter.Canvas(width=400, height=300) 
oid = canvas.create_oval(400/2-10, 300/2-10, 400/2+10, 300/2+10, fill='blue') 
canvas.tag_click = False 
canvas.tag_bind(oid, "<Button-1>", oval_mouse_click) 
canvas.bind("<Button-1>" , canvas_mouse_click) 
canvas.pack() 
root.mainloop() 

Es gibt keinen anderen einfacheren Weg, dies unter Canvas zu handhaben.

0

Ich habe gerade eine verbesserte Lösung auf das ähnliche Problem Python tkinter: stopping event propagation in text widgets tags dort geschrieben.

Die Kernidee ist die gleiche wie in den vorherigen Lösungen: hijack das Canvas Widget durch Bindung mit der gleichen Ereignisfolge wie tag_bind. Die verbesserte Lösung, die ich mit entwickelt habe, ermöglicht es nun, das erwartete return "break" Verhalten von Tks anderen bind + Callback-Paaren zu simulieren. Kurz gesagt:

  1. erstellen einen Wrapper um die wünschten callback, das heißt, eine aufrufbare Klasse Instanz
  2. , wenn die Klasseninstanz aufgerufen wird, laufen callback und ihr Ergebnis überprüfen.
    • wenn das Ergebnis "break" ist, vorübergehend die Ereignispropagierung fallen: bindCanvas das Widget auf das gleiche Ereignis gebunden tag_bind, mit einem leeren Rückruf. Dann nach einer Leerlaufzeit unbind.
    • wenn das Ergebnis nicht "break" ist: nichts tun, wird das Ereignis Canvas propagieren automatisch

Der Link oben ein vollständiges Arbeitsbeispiel mit dem Text Widget listet, aber es ist unmittelbar übertragbar auf die Leinwand Widget.

Verwandte Themen