2013-04-25 25 views
6

Ich habe versucht, nach einer Lösung zu suchen, konnte aber keine finden, die funktioniert. Ich habe eine zweite Liste von tkinter Buttons, und ich möchte ihren Text ändern, wenn es mit der Maus angeklickt wird. Ich habe versucht, dies zu tun:tkinter button Befehle mit Lambda in Python

def create_board(number): 
    print(number) 
    for i in range (0,number): 
     buttonList.append([]) 
     for j in range(0,number): 
      print(i,j) 
      buttonList[i].append(Button(root, text = " ", command = lambda: update_binary_text(i,j))) 
      buttonList[i][j].pack() 

Dann, wenn sie es nennt diese Funktion angeklickt wird:

def update_binary_text(first,second): 
    print(first,second) 
    buttonList[first][second]["text"] = "1" 

Wenn ich auf eine Schaltfläche klicken, es ist einfach nichts tut, ich hatte das Programm zeigen die Indizes der Schaltfläche das wurde geklickt, und alle zeigen 4, 4 (das ist, wenn die Variable Nummer = 5) Gibt es eine Lösung für diese?
Dies ist mein erster Python-Versuch für eine Klasse.

Dank

Antwort

8

Sie dieses Problem durch die Schaffung eines Verschlusses für i und j mit der Schaffung eines jeden Lambda beheben:

command = lambda i=i, j=j: update_binary_text(i, j) 

Sie auch selbst eine Callback-Fabrik mit Referenzen schaffen könnte, um die Schaltfläche Objekte :

def callback_factory(button): 
    return lambda: button["text"] = "1" 

Und dann in Ihrem Initialisierungscode:

+0

WOW! Deine Lösung hat funktioniert! Danke mein Herr! Für jetzt steckte ich mit dem ersten Beispiel fest, das du bekannt gabst. Aber ich werde definitiv das zweite Beispiel studieren, das du auch gezeigt hast. Danke noch einmal! – vap

0

Immer wenn ich eine Sammlung ähnlicher Widgets benötige, finde ich es am einfachsten, sie in ein Objekt einzufügen und eine gebundene Methode als Callback zu übergeben, anstatt Tricks mit Lambda zu spielen. Anstatt also eine Liste wie buttonList[] mit Widgets mit, erstellen Sie ein Objekt:

class MyButton(object): 
    def __init__(self, i, j): 
     self.i = i 
     self.j = j 
     self.button = Button(..., command = self.callback) 

    def callback(self): 
     . . . 

Nun haben Sie eine Liste buttonList[] dieser Objekte, anstatt die Widgets selbst. Um den Text zu aktualisieren, stellen Sie entweder eine Methode dafür bereit, oder greifen Sie direkt auf das Mitglied zu: buttonList[i].button.configure(. . .) Und wenn der Rückruf aktiviert ist, hat es das gesamte Objekt und alle Attribute, die Sie möglicherweise in self benötigen.