2017-07-29 10 views
0

非常に複雑なpython tkinterフォームへのイベント(Ctrl + ZとCtrl + Yの1つ)をバインドしたい(ルートには多くの子フレームがあり、それぞれのイベントにバインドするのは非常に面倒で冗長です)。私はルートにキーをバインドする方法があることを望んだので、フォーカスが子ウィジェットの内側にあってもバインディングがトリガーされるようにしました。私がこれまでに試したのはこれです:Python tkinter以降のすべてのウィジェットへのキーバインド

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()) 

しかし、これは動作していないようです。これには適切な解決策はありますか? (結果が同じでないバインドメソッドも試しました)

+2

'bind'または' bind_all'は、そのために働く必要があります。コマンドで角括弧を使用していることを確認してください。 'self.root.bind(" "、self.undo)' – Novel

+0

ありがとう、愚かな私...しかし、イベント以来ラムダが必要です取り消しとやり直しの署名は明らかに議論を取りません。 – PfannkuchenXD

+0

これを署名に追加します。標準形式は 'def undo(self、event = None):'であり、バインドまたは通常から呼び出すことができます。トレースからそれを呼び出す機能を追加したい場合、 'def undo(self、* args):' – Novel

答えて

1

イベントを正しく指定していません。適切なイベント名は"<Control-z>""<Control-y>"です(<>に注意してください)。

それ以外の場合は、bind_allがまさにあなたが望むものです。

lambdaも使用する必要はありません。ある特定の状況でのみ有用ですが、これはそうではありません。 tkinterが自動的にコールバックに渡すイベントオブジェクトの引数を受け付ける関数への参照を提供するだけです。関数を直接呼び出す場合は、イベント・パラメーターにヌルのデフォルト値を指定します。例えば

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) 
関連する問題