2017-07-29 3 views
0

Ich möchte an Ereignisse (eine für Strg + Z und eine für Strg + Y) an eine Python-tkinter Form binden, die sehr komplex ist (die Wurzel hat viele Kind-Frames und diese auch haben, so verbindlich das Ereignis zu jedem von denen wäre sehr ärgerlich und überflüssig). Ich hoffte, dass es eine Methode gibt, den Schlüssel an den Stamm zu binden, so dass selbst dann, wenn ich mich auf die Kind-Widgets konzentriere, die Bindung ausgelöst wird. Was ich bisher versucht habe, ist dies:Python tkinter Key-Bindung an alle nachfolgenden Widgets

def _init_gui(self, root): 
     """ Initializes all members of the gui""" 
     tkinter.Frame.__init__(self, root) #Superclass init 
     self.root = root 
     width, height = root.winfo_screenwidth(), root.winfo_screenheight() 

     #Most of the code is left out because it is not neccessary 

     self.root.bind_all("Control-z", lambda _: self.undo()) 
     self.root.bind_all("Control-y", lambda _: self.redo()) 

Allerdings scheint dies nicht zu funktionieren. Gibt es dafür eine angemessene Lösung? (Ich habe auch die Bind-Methode mit dem gleichen Mangel an Ergebnis versucht)

+2

'bind' oder' bind_all' sollte das funktionieren. Stellen Sie sicher, dass Sie die spitzen Klammern im Befehl verwenden, und Lambda wird hier nicht benötigt: 'self.root.bind (" ", self.undo)' – Novel

+0

Danke, dumme mich ... Allerdings Lambda wird seit einem Ereignis benötigt wird übergeben und die Signatur von Undo und Redo übernimmt offensichtlich keine Argumente. – PfannkuchenXD

+0

Also fügen Sie es der Signatur hinzu. Die Standardform wäre 'def undo (self, event = None):' damit sie von bind oder normal aufgerufen werden kann. Wenn Sie die Fähigkeit hinzufügen möchten, um es auch aus dem Trace aufzurufen: 'def undo (self, * args):' – Novel

Antwort

1

Sie geben das Ereignis nicht richtig an. Die richtigen Ereignisnamen sind "<Control-z>" und "<Control-y>" (notieren Sie die < und >).

Ansonsten ist bind_all genau das, was Sie wollen.

Es ist auch nicht notwendig, lambda zu verwenden. Es ist nur in einer bestimmten Situation nützlich, und das ist es nicht. Geben Sie nur einen Verweis auf eine Funktion an, die ein Argument für das Ereignisobjekt akzeptiert, das tkinter automatisch an den Callback übergibt. Wenn Sie die Funktion auch direkt aufrufen möchten, geben Sie dem Ereignisparameter einen Null-Standardwert.

Zum Beispiel:

def undo(self, event=None): 
    ... 
def redo(self, event=None): 
    ... 

self.root.bind_all("<Control-y>", self.undo) 
self.root.bind_all("<Control-z>", self.redo) 
Verwandte Themen