Python Tkinter — восстановление исходной привязки клавиш по умолчанию

Я работаю с Python 2.7 и графическим интерфейсом Tkinter на машине Win7.

Бывают ситуации, когда я хочу полностью переопределить нормальное поведение клавиши Tab по умолчанию, но только до тех пор, пока существуют определенные условия. После этого я хочу вернуться к поведению по умолчанию. (Обратите внимание, что на данный момент меня интересует клавиша Tab, но в какой-то момент мне может понадобиться сделать это и для других клавиш.)

Фрагмент кода ниже (не мое фактическое приложение, просто урезанный образец) дает мне полное переопределение, которое я хочу, но у него есть побочный эффект «навсегда» устранение поведения по умолчанию, как только я делаю unbind, отображая вкладку ключ неэффективен:

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), но затем вернуться к привязке/поведению тот ключ как был в вызывающем модуле, как я мог это сделать? Является ли это возможным?


person JDM    schedule 30.01.2014    source источник
comment
Обычно при обычном методе привязки в текстовом виджете, по крайней мере, наличие return "break" в вашем обработчике событий останавливает выполнение привязки по умолчанию, а его отсутствие позволяет ему выполняться (так же, как и другой код в вашем обработчике ). Итак, если вы можете написать обработчик событий с оператором if, где return "break" используется только в ситуации, которую вы хотите переопределить, это может сработать. Однако я не знаю, сработает ли это в вашей ситуации. Вот почему я только публикую комментарий. Вы также должны иметь в виду, что первым параметром в вашем обработчике должно быть событие с привязкой.   -  person Brōtsyorfuzthrāx    schedule 10.06.2014


Ответы (1)


Хорошо, я попробовал и получил ответ для вас. То, что я предложил в своем комментарии, работает. Таким образом, 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()
person Brōtsyorfuzthrāx    schedule 09.06.2014