3

Win7 マシンで Python 2.7 と Tkinter GUI を使用しています。

Tab キーの通常のデフォルト動作を完全にオーバーライドしたい状況がありますが、それは特定の条件が存在する場合に限られます。その後、デフォルトの動作に戻したいと思います。(現時点では、Tab キーに興味がありますが、他のキーについてもこれを行う必要があるかもしれません。)

unbind以下のコード スニペット (私の実際のアプリではなく、単純化されたサンプルにすぎません) は、必要な完全なオーバーライドを提供しますが、Tab キーをレンダリングすると、既定の動作が「永久に」削除されるという副作用があります。無効:

import Tkinter as tk

#Root window
root = tk.Tk()

tabBlock = ''

#Tab override handler
def overrideTab(*args):
    global tabBlock
    if (ctrlChk4.get()==1):
        tabBlock = root.bind_all('<Tab>',stopTab)
    else:
        root.unbind('<Tab>',tabBlock)

def stopTab(*args):
    print 'Tab is overridden'

#Control variable
ctrlChk4 = tk.IntVar()
ctrlChk4.trace('w',overrideTab)

#GUI widgets
fra1  = tk.Frame(root)
chk1 = tk.Checkbutton(fra1,
                      text='First checkbutton')
chk2 = tk.Checkbutton(fra1,
                      text='Second checkbutton')
chk3 = tk.Checkbutton(fra1,
                      text='Third checkbutton')
chk4 = tk.Checkbutton(fra1,
                      text='Tab override',
                      variable=ctrlChk4)

fra1.grid(row=0,column=0,sticky=tk.W,padx=10,pady=10)
chk1.grid(row=0,column=0,sticky=tk.W,padx=(10,0),pady=(5,0))
chk2.grid(row=1,column=0,sticky=tk.W,padx=(10,0),pady=(5,0))
chk3.grid(row=2,column=0,sticky=tk.W,padx=(10,0),pady=(5,0))
chk4.grid(row=3,column=0,sticky=tk.W,padx=(10,0),pady=(5,0))

tk.mainloop()

binda の代わりに aを実行し、バインディング メソッドのパラメーターをorにbind_all設定するバリエーションを試しました。これらのバリエーションはすべて同じ結果をもたらします。一度実行するとデフォルトの動作に戻ることができますが、が有効な間はデフォルトの動作を継続することもできます。add1'+'unbindbind

元のバインディングを「保存して回復」する方法、または「非破壊的に」デフォルトの動作を完全にオーバーライドする方法について、さまざまなオンライン ソースを探しましたが、どちらもうまくいきませんでした。

私がやろうとしていることを達成する方法はありますか?

編集:Tabキーに関しては、元のデフォルトの動作を模倣/置き換えることができることを知っています

root.focus_get().tk_focusNext().focus_set()

...しかし、これは一般的な質問でもあります。特定のモジュール (たとえば、独自のカスタム調整 Tkinter ウィジェット用の独自のカスタム クラスを含むモジュール) のコンテキストでキー (任意のキー) をオーバーライドする必要があるが、その後のバインド/動作に戻る場合そのキーは呼び出し元モジュールにあったので、どうすればそれができますか? 出来ますか?

4

1 に答える 1

4

さて、私はそれを試してみて、あなたに答えを得ました. コメントで提案したことは機能します。要約すると、return "break"それをオーバーライドしたい場合。しないときはしない。bindの代わりに使用しbind_allます。また、引数でまだそうしていない場合は、event パラメーターを考慮に入れます。そうしないと適切に機能しません。実際にはまだ何かをキーにバインドしていますが、指定された状況でデフォルトの機能をオーバーライドするだけです。コードは次のとおりです (Python 2.x と 3.x の両方に適合):

import sys
if sys.version_info[0]<3:
    import Tkinter as tk
else:
    import tkinter as tk

#Root window
root = tk.Tk()

#Tab override handler
def overrideTab(*args):
    root.bind('<Tab>', stopTab)

def stopTab(event=None, *args):
    if ctrlChk4.get()==1:
        print('Tab is overridden')
        return "break"
    else:
        print('Tab is not overridden') #Note that it still prints this.

#Control variable
ctrlChk4 = tk.IntVar()
ctrlChk4.trace('w',overrideTab)

#GUI widgets
fra1  = tk.Frame(root)
chk1 = tk.Checkbutton(fra1,
                      text='First checkbutton')
chk2 = tk.Checkbutton(fra1,
                      text='Second checkbutton')
chk3 = tk.Checkbutton(fra1,
                      text='Third checkbutton')
chk4 = tk.Checkbutton(fra1,
                      text='Tab override',
                      variable=ctrlChk4)

fra1.grid(row=0,column=0,sticky=tk.W,padx=10,pady=10)
chk1.grid(row=0,column=0,sticky=tk.W,padx=(10,0),pady=(5,0))
chk2.grid(row=1,column=0,sticky=tk.W,padx=(10,0),pady=(5,0))
chk3.grid(row=2,column=0,sticky=tk.W,padx=(10,0),pady=(5,0))
chk4.grid(row=3,column=0,sticky=tk.W,padx=(10,0),pady=(5,0))

tk.mainloop()
于 2014-06-09T21:33:44.280 に答える