Шаг 79.
Библиотека Tkinter.
Компоненты и вспомогательные классы. Обработка "горячих клавиш"

    На этом шаге мы рассмотрим особенности назначения "горячих клавиш".

    Многие компоненты поддерживают опцию underline, задающую номер символа, который должен быть подчеркнут. По идее, если нажать комбинацию клавиш вида <Alt>+<Подчеркнутый символ>, элемент управления, в надписи которого присутствует этот символ, либо получит фокус ввода, либо сменит состояние (если это флажок, он будет установлен или сброшен, если это переключатель, он будет установлен, а если это кнопка, она будет нажата). Если же подчеркнутый символ присутствует в надписи (компонент Label), фокус ввода получит компонент, находящийся сразу за надписью.

    Также пункты меню поддерживают опцию accelerator, указывающую обозначение "горячей клавиши" для этого пункта. Опять же, по идее, нажатие такой "горячей клавиши" будет иметь тот же эффект, что и выбор соответствующего пункта меню мышью.

    Проблема в том, что библиотека Tkinter лишь подчеркивает указанный символ или выводит в составе пункта меню указанную для него "горячую клавишу", но не реализует их обработку (проще говоря, если мы нажмем "горячую клавишу", ничего не произойдет). Нам придется реализовать ее самостоятельно.

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


Метод bind_all() привязывает обработчик события ко всем без исключения компонентам, что находятся во всех окнах приложения. К сожалению, это единственный способ обеспечить работу "горячих клавиш" в библиотеке Tkinter.

    В текст ниже показан пример реализации обработки "горячих клавиш", заданных для поля ввода, кнопки, флажка и пункта главного меню.

import tkinter
import tkinter.ttk

class Application(tkinter.ttk.Frame):
    def __init__(self, master=None):
        super().__init__()
        self.pack()
        self.create_widgets()
        self.master.title("Горячие клавиши")

    def create_widgets(self):
        # Создаем главное меню из одного пункта
        window = self.master
        mainmenu = tkinter.Menu(window)
        window["menu"] = mainmenu

        self.menu = tkinter.Menu(mainmenu, tearoff=False)
        self.menu.add_command(label="Открыть", accelerator="Ctrl+0", command=self.mnu)
        mainmenu.add_cascade(label="Файл", menu=self.menu)
        # Создаем элементы управления
        lbl = tkinter.ttk.Label(self, text="Bвeдите значение", underline=8)
        lbl.pack()
        self.ent = tkinter.ttk.Entry(self)
        self.ent.pack()
        self.btn = tkinter.ttk.Button(self, text="Выполнить", underline=0, 
             command=self.but)
        self.btn.pack()
        self.chk = tkinter.ttk.Checkbutton(self, text="Установить", underline=0)
        self.chk.pack()

        # Выполняем привязку к событиям обработчиков, которые реализуют
        # обработку "горячих клавиш"
        # У надписи для поля ввода мы подчеркнули букву "з".
        # Следовательно, нам следует обрабатывать нажатие комбинации
        # клавиш <Alt>+<P>, ведь именно на клавише с латинской буквой "р"
        # находится кириллическая буква "з"
        self.bind_all("<Alt-KeyPress-p>", lambda evt: self.ent.focus_set())
        # Аналогичным образом обрабатываем "горячие клавиши", указанные
        # для кнопки и флажка
        self.bind_all("<Alt-KeyPress-d>", lambda evt: self.btn.invoke())
        self.bind_all("<Alt-KeyPress-e>", lambda evt: self.chk.invoke())
        # Обрабатываем "горячую клавишу" для пункта "Открыть" меню.
        self.bind_all("<Control-KeyPress-0>", lambda evt: self.menu.invoke(0))

    def mnu(self):
        # Удаляем содержимое поля
        self.ent.delete(0, tkinter.END)
        # Выводим в него текст
        self.ent.insert(0, "Пункт меню.")

    def but(self):
        self.ent.delete(0, tkinter.END)
        self.ent.insert(0, "Кнопка.")
        
root = tkinter.Tk()
app = Application(master=root)
root.mainloop()
Архив с файлом можно взять здесь.


Рис.1. Демонстрация работы "горячих клавиш"

    Со следующего шага мы начнем рассмотривать задание и использование стандартных диалоговых окон.




Предыдущий шаг Содержание Следующий шаг