Изучаем как работает фокус в wxPython — wxPython #33

автор

Существуют всего два фокус события, применение которых я видел лично: wx.EVT_SET_FOCUS и wx.EVT_KILL_FOCUS. Событие EVT_SET_FOCUS запускается, когда виджет получает фокус, например, когда вы кликаете на пустую панель или же наводите курсор на виджет TextCtrl. Когда вы кликаете за пределами виджета или переключаетесь на другое диалоговое окно, запускается процесс EVT_KILL_FOCUS.

Приобретение (эквайринг) фокуса

Одно из нескольких «фишек», которые я заметил, листая еженедельную почтовую рассылку от wxPython, было то, что wx.Panel принимает фокус только тогда, когда у него нет дочернего виджета, который бы принял фокус вместо него. Проще будет объяснить всё это с помощью нескольких примеров.

Этот код отображает пустую панель, на которой ничего нет. Вы заметите, что stdout незамедлительно получит надпись «panel received focus!», если вы используете Windows или Mac. На Linux вы получите это сообщение только если кликните на саму панель. Теперь, если вы добавите TextCtrl или кнопку, то фокус получат именно они, и хэндлер событий OnFocus не будет запущен. Попробуйте запустить код, расположенный ниже, чтобы увидеть, как это работает:

Забавы ради, попробуйте вставить в эту панель StaticText вместо TextCtrl. Какой виджет по-вашему получит фокус? В зависимости от того, на какой платформе запущен следующий код, вы можете прийти к тому, что ничего не находится в фокусе. Со мной подобное произошло на Linux. На Windows 7, панель была в фокусе. В то время, когда я ещё пользовался Windows XP, фокус получил Frame. В любом случае, давайте взглянем на код:

Главное, что можно вынести из этих экспериментов, это то, что wx.Window.FindFocus() является очень полезной функцией, и она поможет вам, когда вы будете пытаться выяснить то, почему фокус находится не в том месте, в котором вы предполагали. Конечно, некоторые из вас знают что, когда курсор мыши попадает в рамку, и что информацию об этом можно получить посредством EVT_ENTER_WINDOW (которому я не буду уделять внимания в этой статье.

Потеря фокуса

Теперь давайте быстренько разберёмся с wx.EVT_KILL_FOCUS. Я создал простой пример, содержащий всего два элемента контроля. Попробуйте догадаться, что произойдёт, если вы переключитесь между ними.

Как вы могли предполагать, когда вы переключитесь между ними, TextCtrl может запустить как отмену фокуса, так и запуск фокуса. Как узнать какой из виджетов запускает эти события? Посмотрите на мои методы Бинда. Только текстовые контроли могут запускать события фокуса. В качестве упражнения попробуйте забиндить кнопку и на эти хэндлеры, а затем вывести на экран сообщение о том, какие виджеты запускают определённые события.

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

По словам Робина Данна, wx.lib.scrolledpanel использует это событие. Один из моих читателей поделился со мной удобным случаем, в котором можно использовать wx.EVT_CHILD_FOCUS: «Вы можете использовать его в рамке, чтобы просто очистить панель статуса посредством нажатия на любой другой дочерний виджет. Таким образом вы не получите старое сообщение «â€oeErrorâ€􀣭» или подобный текст в панели статуса, когда вы нажмёте на другой дочерний виджет.» (hattip @devplayer)

Итоги

Теперь вы уже должны знать достаточно о том, как работает фокусировка в wxPython, так что можете использовать её в своих приложениях. Также вы узнали о том, как выявить фокус в различных обстоятельствах. Мы также написали приложение, которое может дать нам знать о том, когда оно в фокусе, а когда нет. И, наконец, мы узнали, как теряется фокус, что может быть также очень полезно в некоторых случаях.

Вам может быть интересно

Scroll Up