Spec-Zone.ru › Qt 5.9

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

Виджеты Qt обрабатывают фокус клавиатуры привычным для GUI способом.

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

Движение фокуса

Принятые правила для направления фокуса клавиатуры на конкретный виджет:

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

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

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

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

Нажатие клавиши 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. Хотя оно перемещает фокус в виджет, для виджетов редактора оно также перемещает курсор текста (внутренний фокус виджета) в точку щелчка мышью.

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

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

Мы рекомендуем поддерживать щелчок для перемещения фокуса для виджетов, поддерживающих ввод текста, и избегать его для большинства виджетов, где щелчок мышью имеет другое действие. (Для кнопок также рекомендуется добавить сочетание клавиш: 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-5.9/focus.html

Spec-Zone.ru

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