Обнаруживаем ключевые и Char-события — wxPython #20

В этой статье я расскажу, как обнаружить особые нажатия горячих клавиш и почему это может быть полезным. В самом деле, обнаруживать такие клавиши достаточно просто, но иногда удивляет то, что один виджет ведёт себя совершенно отлично от другого. Самое сложное наступает, когда нужно захватить EVT_CHAR.

Примечание: примеры, которые я рассматриваю в данной статье, не работают на Mac OSX El Capitan.

Сначала я расскажу о событиях, вызываемых горячими клавишами, wx.EVT_KEY_DOWN и wx.EVT_KEY_UP, а потом уже погружусь в сложности wx.EVT_CHAR.

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Обнаружение событий, связанных с горячими клавишами

Обнаружение событий в wxPython, связанных с горячими клавишами, в wxPython – процесс достаточно простой. Всё, что нужно, это выяснить код какой клавиши вы хотите обнаружить в документации wxPython, или обнаружить все клавиши и запомнить (читай, записать) все коды, которые срабатывают при нажатии горячих клавиш. Давайте посмотрим:

Вы заметите, что в данном фрагменте кода виджетами последствий являются только панель и кнопка. Я привязываю клавишу к EVT_KEY_DOWN и проверяю в хэндлере, нажимал ли пользователь пробел. Событие запускается только если клавиша была нажата. Вы также заметите, что я вызывал event.Skip в конце. Если вы не вызовете event.Skip, то клавиша будет поглощена и не будет запущено соответствующее событие горячей клавиши. Это не повлияет на кнопку, но в командной строке события горячих клавиш подходят для обнаружения верхнего и нижнего регистров, ударений, умляутов и им подобных.

Я использовал подобный метод для отслеживания нажатий клавиш-стрелок в моём приложении, которое являлось таблицей. Я хотел быть способным обнаруживать данные клавиши во время редактирования ячейки, чтобы нажатие стрелки делало активно другую ячейку. Это не поведение по умолчанию. В сетке, каждая ячейка имеет собственный редактор, а нажатие клавиш-стрелок перемещало курсор внутри ячейки.

Когда вы запускаете код, написанный выше, и нажимаете пробел, то должны увидеть что-то похожее на этот скриншот:

Обнаруживаем ключевые и Char-события - wxPython #20

Просто эксперимента ради, я создал пример, похожий на тот, что вы видите выше, только теперь я привязал события, связанные с нажатием клавиш вверх и вниз к двум разным виджетам. Для этого понадобиться следующий код:

Когда запустите код, написанный выше, попробуйте нажать на кнопку и затем на пробел. Затем переместите фокус с текстового поля и нажмите клавишу «Delete». Когда вы закончите, то должны увидеть что-то вроде этого скриншота:

Обнаруживаем ключевые и Char-события - wxPython #20

Попробуйте нажать другие клавиши, и вы увидите, что коды горячих клавиш распечатались для каждой клавиши.

Соглашусь, этот код скорее для иллюстрации. Главное, что вам нужно знать это то, что вы действительно не используете EVT_KEY_UP до тех пор, пока вам не понадобится отслеживать несколько комбинаций из двух-трёх клавиш вроде CTRL+K+Y, или что-то подобное (в качестве дополнительного замечания: ознакомитесь с возможностями wx.AcceleratorTable). Так как я не делаю этого в своём примере, стоит отметить, что если вы проверяете клавишу CTRL, то лучше будет использовать event.CmdDown(), чем event.ControlDown. Причина в том, что CmdDown является эквивалентом для ControlDown на Windows и Linux, но в Mac он симулирует клавишу Command.  Таким образом, CmdDown лучший кроссплатформенный способ проверки нажатия клавиши CTRL.

И это, пожалуй, всё, что вам нужно знать о событиях, связанных с горячими клавишами. Теперь давайте разберёмся с char-событиями.

Обнаружение с char-событий

Обнаружение с char-событий немного сложнее, но не слишком. Давайте взглянем на пример, чтобы понять какие существуют отличия.

Я думаю, что главное отличие в том, что вы захотите проверять ударения или международные знаки. Таким образом, у вас будут сложные условия, которые проверяют были ли нажаты определённые клавиши и в каком порядке. Робин Данн (создатель wxPython) сказал, что wxSTC проверять и события, связанные с горячими клавишами, и char-события. Если в ваши планы входит поддержка пользователей за пределами англоязычных стран, вы, скорее всего, захотите узнать, как это работает.

Цитата Робина Дана: «Если вы хотите, чтобы события, связанные с горячими клавишами, выполняли «команды» внутри приложения, используйте сырые значения в хэндлере EVT_KEY_DOWN. Как бы то ни было, если в перечень возможностей приложения входит ввод текста, тогда оно должно использовать готовые значения в хэндлере события EVT_CHAR, чтобы нормально обрабатывать не английскую раскладку клавиатуры и другие редакторы методов ввода. (Примечание: события keydown/keyup считаются сырыми, в то время как char-события считаются готовыми).

Как мне объяснил Робин Дан, во всех раскладках клавиатуры, кроме английской, заготовка клавиш для char-событий является мэппингом физических клавиш к национальной раскладке клавиатуры, чтобы появлялись символы с ударениями, умляутами и прочие.

Когда вы будете тестировать мою демо-версию, вы заметите, что в нём коды, привязанные к горячим клавишам, активируются, когда вы их нажимаете. Если вы хотите увидеть коды для особых комбинаций клавиш, попробуйте нажать CTRL или SHIFT одновременно с другой клавишей. Вам также нужно иметь возможность обнаруживать ALT, но я заметил, что эта опция не работает ни на моём компьютере с Windows 7, ни на моём макбуке.

Итоги

Теперь вы можете написать своё собственное приложение, использующее захват клавиш и char-события. Вам также может пригодится другая статья на похожую тему, которая называется AcceleratorTable. Этот класс позволяет разработчикам захватывать комбинации клавиш, которые пользователь нажимает в то время, как использует программу. Так что прочтите её, когда будет возможность.