Доброго времени суток, читатели, зрители моего канала programmer's notes. Не забывайте подписываться и писать свои комментарии к моим статьям и видео.
Ещё об обработке нажатия клавиш - события keyPressEvent
И я снова возвращаю к вопросу об обработке нажатия клавиш. Мы говорили об этом вот в этой статье. Посмотрите её перед прочтением этой
По сути, я буду говорить о том же. Просто сделаю акцент на передаче события из элемента управления в главное окно. Как то в дискуссии мне написали: ты что, дядя, не понимаешь, что это Qt5, здесь сигналы надо обрабатывать, забудь про переопределение событий. Не соглашусь с этим, просто потому что люблю детальную обработку, а не готовый сформированный сигнал. Разве вам не интересно прописать всё своими руками.
Программа создаёт окно и два элемента на нём: кнопка и строка редактирования (см. Рисунок 1).
Пояснение к программе
- Надо иметь в виду, что когда элемент окна получает фокус ввода, то нажатие клавиш и щелчки кнопкой обрабатываются обработчиками событий, наследуемых от родительского класса (keyPressEvent(), mousePressEvent()). При этом эти обработчики по умолчанию могут передавать обработку уже обработчикам окна или не передавать в зависимости от логики обработки. Например, элемент строка редактирования не передаёт дальше нажатия тех клавиш, которые связаны с редактированием. Другие же нажатия от обработчика строки редактирования переходят к обработчику окна, где расположен элемент.
- Для того, чтобы обрабатывать самим нажатия клавиш мы просто в наследнике класса - элемента окна (или в наследнике класса окна) переписываем метод keyPressEvent(). При этом метод получает параметр (event, в нашей программе он обозначается просто буквой e) - информацию о нажатой клавише. В нашей программе переписаны обработчики нажатия клавиш и элементов окна и самого окна.
- Что можно сделать, получив информацию о нажатой клавише? 1. Вы можете просто заблокировать нажатие клавиши. Как? Например, просто поставить в обработчике одну команду pass. 2. Передать на обработку стандартного родительского обработчика. Это можно сделать так super().keyPressEvent(e), или имя класса и имя метода: QPushButton.keyPressEvent(self, e) или QLineEdit.keyPressEvent(self, e). При этом передаст ли такой обработчик потом управление обработчику окна - это на его усмотрение. 3. Сделать что-то не передавать никаким обработчикам. См. пункт (1). 4. Сделать что-то и передать стандартным обработчикам. См. пункт (2). 5. Передать сразу обработчику родительского окна. У нас это self.wg.keyPressEvent(e). 6. Сделать что-то и передать обработчику родительского окна. См. пункт (5).
- В программе есть один не большой нюанс. При нажатии ESC или Delete появляется окно с вопросом: нужно ли выходить из программы. Нюанс в том, что нажатие ESC и так передаётся родительскому окну, так как редактором строки не обрабатывается. А вот нажатие клавиши Delete родительскому окну не передаётся. Поэтому мы проверяем в обработчик строки редактирования:
if e.key() == Qt.Key_Escape or e.key() == Qt.Key_Delete:
И потом, если условие выполнено сразу передаём управление
self.wg.keyPressEvent(e)
Что касается кнопки, то там нажатие этих клавиш сразу передаётся родительскому окну, поэтому нажатие этих клавиш в объекте Кнопка обрабатывать не нужно. Зато мы обрабатываем там Spacе и Enter, но здесь всё очевидно.
Ну, пока всё!
Пишите свои предложения и замечания, и занимайтесь программированием, а также проектированием баз данных, хотя бы для поддержания уровня интеллекта.