2010-11-28 11 views
7

In Tkinter habe ich mehrere Widgets an die linke Maustaste gebunden. Sie alle lösen beim Anklicken das gleiche Ereignis aus.Das Widget erhalten, das ein Ereignis ausgelöst hat?

Wie kann ich wiederherstellen, welches Widget angeklickt wurde?

Ich möchte es so, wenn Label2 gedrückt wurde, könnte ich wiederherstellen, dass Label2 das Widget war, das innerhalb des Ereignisses gedrückt wurde, das ausgelöst wurde.

Antwort

8
def f(event): 
    caller = event.widget 
8

Sie haben ein paar Optionen. Eine Möglichkeit besteht darin, auf das Attribut widget des Ereignisobjekts zuzugreifen. Eine andere Möglichkeit besteht darin, eine Objektreferenz an Ihre Funktion zu übergeben. Hier ist ein Beispiel, das jeweils einen verwendet.

import Tkinter as tk 

def OnClickA(event): 
    print "you clicked on", event.widget 
    event.widget.config(text="Thank you!") 


def OnClickB(event, obj): 
    print "you clicked on", obj 
    obj.config(text="Thank you!") 

root = tk.Tk() 
l1 = tk.Label(root, text="Click me") 
l2 = tk.Label(root, text="No, click me!") 
l1.pack() 
l2.pack() 

l1.bind("<1>", OnClickA) 
l2.bind("<1>", lambda event, obj=l2: OnClickB(event, obj)) 

root.mainloop() 
2

Klingt wie alle Ihre Widgets einen Event-Handler teilen. Dieser Auszug aus der Tkinter 8.4 Reference von John W. Shipman - NM Tech, kann helfen.

30.7. The extra arguments trick

Manchmal möchten Sie andere Argumente neben der Ereignis zu einem Handler zu übergeben.

Hier ist ein Beispiel. Angenommen, Ihre Anwendung hat ein Array von zehn Checkbuttons, deren Widgets in einer Liste self.cbList, indexiert von die Checkbutton-Nummer in range(10) gespeichert sind.

Nehmen wir weiter an, dass Sie ein Handler namens .__cbHandler für <Button-1> Ereignisse in alle zehn dieser Checkboxen schreiben möchten. Der Handler kann erhält den tatsächlichen Checkbutton Widget , die es unter Bezugnahme auf das .widget Attribut des Event Objekts ausgelöst, die in übergeben werden, aber wie findet es in self.cbList Index, die Checkbutton ist out?

Es wäre schön, unseren Handler mit einem zusätzlichen Argumente für die Checkbutton-Nummer, so etwas wie dies zu schreiben:

def __cbHandler (self, event, cbNumber): 

Aber Event-Handler übergeben nur eine Argument sind, das Ereignis. Daher können wir die obige Funktion nicht verwenden, da die Anzahl der Argumente nicht mit übereinstimmt.

Glücklicherweise bietet Python die Fähigkeit Standardwerte für die Funktion Argumente bietet uns einen Ausweg. Haben Sie einen Blick auf diesen Code:

def __createWidgets (self): 
     ? 
     self.cbList = [] # Create the checkbutton list 
     for i in range(10): 
      cb = Checkbutton (self, ?) 
      self.cbList.append (cb) 
      cb.grid(row=1, column=i) 
      def handler (event, self=self, i=i): # [1] 
       return self.__cbHandler (event, i) 
      cb.bind ("<Button-1>", handler) 
     ? 
    def __cbHandler (self, event, cbNumber): 
     ? 

# [1] Diese Zeilen definieren eine neue Funktion handler die drei Argumente erwartet.Das erste Argument ist das Event Objekt an alle Ereignis Handler übergeben, und die zweite und dritte Argumente werden auf ihre Standard Werte gesetzt werden? Die zusätzlichen Argumente müssen wir übergeben.

Diese Technik kann auf erweitert werden, um eine beliebige Anzahl von zusätzlichen Argumenten an Handler zu liefern.

Ein etwas prägnante Weise, dies zu tun, wie Bryan Oakley für die zweite Taste funktioniert in his answer, ist auf jede Handler-Funktion in-line mit einem Lambda zu definieren, d.h .:

def __createWidgets (self): 
    ? 
    self.cbList = [] # Create the checkbutton list 
    for i in range(10): 
     cb = Checkbutton (self, ?) 
     self.cbList.append (cb) 
     cb.grid(row=1, column=i) 
     cb.bind ("<Button-1>", lambda event, self=self, i=i: 
            self.__cbHandler(event, i)) 
    ? 
def __cbHandler (self, event, cbNumber): 
    ? 
Verwandte Themen