Spec-Zone.ru › Qt 6.0

Фокус клавиатуры в виджетах

Виджеты Qt обрабатывают фокус клавиатуры так, как это стало обычным в графических интерфейсах.

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

Перемещение фокуса

Обычаи, которые развились для направления фокуса клавиатуры на определенный виджет, таковы:

  1. Пользователь нажимает Tab (или Shift+Tab).
  2. Пользователь щелкает по виджету.
  3. Пользователь нажимает сочетание клавиш.
  4. Пользователь использует колесо мыши.
  5. Пользователь перемещает фокус в окно, и приложение должно определить, какой виджет внутри окна должен получить фокус.

Каждый из этих механизмов перемещения отличается, и разные типы виджетов получают фокус только в некоторых из них. Мы рассмотрим каждый из них поочерёдно.

Клавиши Tab или Shift+Tab

Нажатие Tab является наиболее распространенным способом перемещения фокуса с помощью клавиатуры. (Иногда в приложениях для ввода данных Enter выполняет ту же функцию, что и Tab; это легко достигается в Qt путём реализации фильтра событий event filter.)

Нажатие Tab во всех используемых сегодня оконных системах перемещает фокус клавиатуры к следующему виджету в циклическом списке внутри окна. Tab перемещает фокус по циклическому списку в одном направлении, Shift+Tab — в другом. Порядок, в котором нажатия Tab перемещают фокус от виджета к виджету, называется порядком табуляции.

Вы можете настроить порядок табуляции с помощью QWidget::setTabOrder(). (Если этого не сделать, Tab обычно перемещает фокус в порядке создания виджетов.) Qt Designer предоставляет средства для визуального изменения порядка табуляции.

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

Например, в диалоговом окне ввода данных может быть поле, которое необходимо только в одном проценте всех случаев. В таком диалоговом окне Tab может пропустить это поле, и диалоговое окно может использовать один из этих механизмов:

  1. Если программа может определить, нужно ли поле, она может переместить фокус туда, когда пользователь закончит ввод и нажмёт ОК, или когда пользователь нажмёт Enter после заполнения других полей. В качестве альтернативы включите поле в порядок табуляции, но отключите его. Включите его, если это станет уместным с учётом того, что пользователь ввёл в другие поля.
  2. Метка поля может содержать сочетание клавиш, которое перемещает фокус в это поле.

Ещё одним исключением из поддержки Tab являются виджеты ввода текста, которые должны поддерживать вставку табуляций; почти все текстовые редакторы относятся к этому классу. Qt обрабатывает Ctrl+Tab как Tab, а Ctrl+Shift+Tab как Shift+Tab, и такие виджеты могут переопределить QWidget::event() и обработать Tab до вызова QWidget::event() для получения обычной обработки всех остальных клавиш. Однако, поскольку некоторые системы используют Ctrl+Tab для других целей, и многие пользователи не знают о Ctrl+Tab, это не является полным решением.

Нажатие пользователем на виджет

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

Нажатие для перемещения фокуса немного мощнее, чем Tab. Хотя оно перемещает фокус в виджет, для виджетов-редакторов оно также перемещает курсор текста (внутренний фокус виджета) в место, где щелкнули мышкой.

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

Например, в текстовом редакторе, когда пользователь щелкает по кнопке инструмента «Жирный», что должно произойти с фокусом клавиатуры? Должен ли он остаться там, где он был, почти наверняка в поле редактирования, или он должен переместиться на кнопку «Жирный»?

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

В Qt только функция QWidget::setFocusPolicy() влияет на фокус при щелчке.

Нажатие пользователем сочетания клавиш

Нетипично, чтобы сочетания клавиш перемещали фокус. Это может происходить неявно при открытии модальных диалогов, но также и явно с помощью акселераторов фокуса, таких как те, что предоставляются QLabel::setBuddy(), QGroupBox и QTabBar.

Мы рекомендуем поддерживать фокус сочетаний клавиш для всех виджетов, к которым пользователь может захотеть перейти. Например, диалог вкладок может иметь сочетания клавиш для каждой из его страниц, поэтому пользователь может нажать, например, Alt+P, чтобы перейти на страницу Pечать. Легко переусердствовать с этим: есть всего несколько клавиш, и также важно предоставлять сочетания клавиш для команд. Alt+P также используется для Вставки, Воспроизведения, Печати и Печать сюда в списке Стандартные сочетания клавиш, например.

Поворот колёса мыши

В Microsoft Windows использование колеса мыши всегда обрабатывается виджетом, у которого есть фокус клавиатуры. В macOS и X11 это обрабатывается виджетом, который получает другие события мыши.

Способ, которым Qt обрабатывает эту разницу платформ, заключается в том, что виджеты перемещают фокус клавиатуры при использовании колеса. С правильной политикой фокуса на каждом виджете приложения могут работать адекватно на Windows, macOS и X11.

Перемещение фокуса в это окно

В этой ситуации приложение должно определить, какой виджет внутри окна должен получить фокус.

Это может быть просто: если фокус был в этом окне раньше, то последний виджет, который имел фокус, должен его вернуть. Qt делает это автоматически.

Если фокус никогда не был в этом окне раньше и вам известно, с какого виджета фокус должен начаться, вызовите QWidget::setFocus() для виджета, который должен получить фокус, перед вызовом QWidget::show() для него. Если этого не сделать, Qt выберет подходящий виджет.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.0/focus.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API