2014-01-30 43 views
3

我正在使用Python 2.7和Win7機器上的Tkinter GUI。Python Tkinter - 恢復原始默認密鑰綁定

有些情況下我想完全覆蓋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() 

我已經試過變化爲bind而不是bind_all,並且還將綁定方法的參數add設置爲1'+'。這些變體都給了我相同的結果:一旦我做了unbind,它們讓我恢復默認行爲,但它們也允許默認行爲在bind生效時繼續。

我已經搜索了各種在線資源,以便「保存和恢復」原始綁定,或者「非破壞性」地完成默認行爲的完全覆蓋,但是兩次都沒有運氣。

有什麼辦法可以完成我想要做的事情嗎?

編輯:當涉及到Tab鍵,我知道我可以模仿/與

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

取代原來的默認行爲......但是這也是一個通用的問題。如果我需要在某個模塊的上下文中重寫某個鍵(例如,包含我自己的自定義類,用於我自己定製的Tkinter Widget)的關鍵字 - 任意鍵,然後返回到綁定/行爲那個鍵在調用模塊中,我怎麼能這樣做?可能嗎?

+0

通常情況下,在文本插件的常規綁定方法,至少,'回報「破發」'在你的事件存在處理程序停止執行缺省綁定,並且缺少它可以執行(以及對處理程序中的其他代碼進行排序)。所以,如果你可以寫一個帶有if語句的事件處理程序,其中「return」break「'只在你想重寫的情況下才有效。但是,我不知道它是否會適用於您的情況。這就是爲什麼我只發表評論。您還需要記住,您處理程序中的第一個參數應該是帶有綁定的事件。 – Shule

回答

3

好的,我試了一下,得到了一個答案。我在評論中建議的作品。總之,當你想覆蓋它時,return "break"。不要當你不這樣做。使用bind而不是bind_all。而且,如果您尚未在參數中這樣做,請考慮事件參數,否則將無法正常工作。你實際上仍然將某些東西綁定到鍵上,但它只是在特定情況下覆蓋默認功能。下面的代碼(適用於兩種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()