Используя Python 3.7.3, как отключить привязку клавиш Tkinter к фону «Tab» - PullRequest
0 голосов
/ 22 октября 2019

Я пытаюсь перехватить нажатие клавиши Tab без явной привязки к ней на уровне корня или фрейма, так как это увеличит сложность больше, чем хотелось бы. Я действительно не хочу привязывать простой обработчик к каждой кнопке.

Я хочу знать две вещи:

  1. Как перехватить / отключить фоновую привязку клавиш "Tab"?
  2. Пробел запускает команду, связанную с этой кнопкой, после вкладки (даже если вы вручную вызываете widget.focus_set () для другого виджета, который является текущим с вкладкой): как мне это предотвратить?

По какой-то причине Tkinter обрабатывает клавишу Tab для автоматического перехода к следующему объекту. Я не хочу этого в моем случае. Я также попытался "вернуть" прерывание "на основе этого ответа , но, похоже, он не работает, или обработчик события" _get_key "происходит после привязки фона.

class testFocus:
    btns = { }
    string = ''
    NumberCharList = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'period', 'comma', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    def __init__(self, root):
        self.top = root
        self.top.bind('<Key>', self._get_key)
        self.frame = tk.Frame(self.top)
        self.frame.pack()

        self.var = tk.StringVar(value='Type: ')
        self.lbl = tk.Label(self.frame, textvariable=self.var)
        self.lbl.pack()

        for i in range(15):
            self.btns[i] = tk.Button(self.frame, text=f'Click {i}', command=lambda x=i: print(x))
            self.btns[i].pack()

    def _get_key(self, event):
        print('Root._get_key.event.keysym: ', event.keysym)
        print(root.focus_get())
        if event.keysym in self.NumberCharList:
            self.string += event.keysym
            self.var.set(self.string)
        elif event.keysym == 'Tab':
            print('TAB!') # NOT WORKING...WHY?
        elif event.keysym == 'Delete':
            self.string = ''
            self.var.set(self.string)
        elif event.keysym == 'BackSpace':
            self.string = self.string[:-1]
            self.var.set(self.string)
        # ... other code that handles specific key presses.
        print(root.focus_get())


if __name__ == '__main__':

    root = tk.Tk()
    root.geometry(f"800x480+{int(root.winfo_screenwidth() / 8)}+{int(root.winfo_screenheight() / 6)}")
    root.attributes('-fullscreen', False)
    root.title('Tests')
    root.resizable(width=False, height=False)
    app = testFocus(root)
    root.mainloop()

Вывод на вкладку:

Root._get_key.event.keysym:  Tab
.
.
Root._get_key.event.keysym:  Tab
.!frame.!button
.!frame.!button
Root._get_key.event.keysym:  Tab
.!frame.!button2
.!frame.!button2
Root._get_key.event.keysym:  Tab
.!frame.!button3
.!frame.!button3
Root._get_key.event.keysym:  Tab
.!frame.!button7
.!frame.!button7
Root._get_key.event.keysym:  Tab
.!frame.!button8
.!frame.!button8
Root._get_key.event.keysym:  Tab
.!frame.!button9
.!frame.!button9
Root._get_key.event.keysym:  Tab
.!frame.!button10
.!frame.!button10
Root._get_key.event.keysym:  Tab
.!frame.!button12
.!frame.!button12

1 Ответ

1 голос
/ 22 октября 2019

Как перехватить / отключить фоновую привязку клавиш "Tab"?

Поведение по умолчанию для вкладок основано на привязке к тегу "all" привязки. Вы можете удалить эту привязку, чтобы удалить поведение вкладки по умолчанию.

root.unbind_all("<Tab>")

В зависимости от базовой версии tk, которую использует ваш python, возможно, она использует привязку к <<NextWindow>>, а не непосредственно на клавише табуляции,В этом случае вам необходимо отменить привязку виртуального события <<NextWindow>> аналогичным образом:

root.unbind_all("<<NextWindow>>")

Если вы хотите удалить вкладку поведения для следующего окна, вы, вероятно, захотитеудалите его и для предыдущего окна. Эта привязка предназначена для виртуального события <<PrevWindow>>

root.unbind_all("<<PrevWindow>>")

Пробел запускает команду, связанную с этой кнопкой, после вкладки (даже если вы вручную вызываете widget.focus_set () для другого виджета, которыйтекущая вкладка одна): как мне предотвратить это?

Это абсолютно не произойдет. Клавиша пробела может вызвать кнопку, только если она имеет фокус, или вы явно задали собственную привязку для обработки клавиши пробела в других виджетах.

...