Tkinterでバインドイベントハンドラーを取得する
-
02-07-2019 - |
質問
メソッドをTkinter要素のイベントにバインドした後、メソッドを元に戻す方法はありますか?
>>> root = Tkinter.Tk()
>>> frame = Tkinter.Frame(root, width=100, height=100)
>>> frame.bind('<Button-1>', lambda e: pprint('Click')) # function needed
>>> frame.pack()
>>> bound_event_method = frame.???
解決
tk C APIでこれを行うための関連する呼び出しは、 Get_GetCommandInfo どの
コマンドに関する情報を配置します 示されているTcl_CmdInfo構造内 to by infoPtr
ただし、この関数は _tkinter.c のどこでも使用されていませんpythonトラフによって使用されるtkのバインディングであるa> Tkinter.py 。
したがって、tkinterからバインドされた関数を取得することは不可能です。その機能を自分で覚えておく必要があります。
他のヒント
Tcl / Tkでこれを行う標準的な方法は簡単です。最終引数なしで同じbindコマンドを使用します。
bind .b <Button-1> doSomething
puts "the function is [bind .b <Button-1>]"
=> the function is doSomething
Tkinterでも同様のことができますが、残念ながら結果はそれほど有用ではありません:
e1.bind("<Button-1>",doSomething)
e1.bind("<Button-1>")
=> 'if {"[-1208974516doSomething %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y %D]" == "break"} break\n'
明らかに、Tkinterはカバーの下で多くのジャグリングを行っています。 1つの解決策は、これを覚えておく小さなヘルパープロシージャを記述することです。
def bindWidget(widget,event,func=None):
'''Set or retrieve the binding for an event on a widget'''
if not widget.__dict__.has_key("bindings"): widget.bindings=dict()
if func:
widget.bind(event,func)
widget.bindings[event] = func
else:
return(widget.bindings.setdefault(event,None))
次のように使用します:
e1=Entry()
print "before, binding for <Button-1>: %s" % bindWidget(e1,"<Button-1>")
bindWidget(e1,"<Button-1>",doSomething)
print " after, binding for <Button-1>: %s" % bindWidget(e1,"<Button-1>")
上記のコードを実行すると、次のようになります:
before, binding for <Button-1>: None
after, binding for <Button-1>: <function doSomething at 0xb7f2e79c>
最後の警告として、私はTkinterをあまり使用しないので、ウィジェットインスタンスに属性を動的に追加することの影響がわからない。無害なようですが、そうでない場合は、常にグローバル辞書を作成してバインディングを追跡できます。
そうではないようです...必要な場合は自分で保存するか、非匿名関数を使用してください。
また、コードは書かれたとおりに機能しません: lambda
関数はステートメントではなく式のみを含むことができるため、 print
は禁止です(これはPython 3.0( print()
が関数になったとき)。