Widget 鍵盤聚焦

Qt 小部件處理鍵盤聚焦的方式,已變為 GUI (圖形用戶界麵) 的習慣。

基本問題是,用戶擊鍵可以指嚮屏幕中的任何幾個窗口,且打算在窗口內的任何幾個 Widget 中。當用戶按下鍵時,他們期望轉到正確位置,且軟件必須轉到滿足這種預期。係統必須確定擊鍵指嚮哪個應用程序,該應用程序中的哪個窗口,及該窗口中的哪個 Widget。

聚焦運動

把鍵盤聚焦指嚮特定 Widget 的自定義演變,是這些:

  1. 用戶按下 Tab (或 Shift+Tab ).
  2. 用戶點擊 Widget。
  3. 用戶按下鍵盤快捷方式。
  4. 用戶使用鼠標滾輪捲。
  5. 用戶移動聚焦到窗口,且應用程序必須確定窗口中的哪個 Widget 應獲得聚焦。

這些運動機製各不相同,且不同類型的 Widget 隻接收它們中某些的聚焦。我們將依次分彆介紹它們。

Tab 或 Shift+Tab

按下 Tab 是到目前為止,使用鍵盤移動聚焦的最常見方式 (有時,數據錄入應用程序中的 Enter 所做的如同 Tab ;可以很輕鬆達成這,在 Qt 中通過實現 事件過濾器 )。

按下 Tab ,在常用的現今所有窗口係統中,把鍵盤聚焦移到每個窗口循環列錶中的下一 Widget。 Tab 聚焦按某個方嚮沿循環列錶移動, Shift+Tab 按其它方嚮。次序對於 Tab 按下從 Widget 移到 Widget 稱為 Tab 次序。

可以定製選項卡次序使用 QWidget::setTabOrder () (若不, Tab generally moves focus in the order of widget construction.) Qt Widgets Designer provides a means of visually changing the tab order.

由於按下 Tab 如此常見,大多數可以擁有聚焦的 Widget 都應支持 Tab 聚焦。主要例外是不常使用的 Widget,且有一些鍵盤加速器 (或錯誤處理程序) 會移動聚焦。

For example, in a data entry dialog, there might be a field that is only necessary in one percent of all cases. In such a dialog, Tab 可以跳過此字段,且對話框可以使用這些機製之一:

  1. 若程序可以確定是否需要字段,它可以移動聚焦到那裏,當用戶完成錄入並按下 OK ,或當用戶按下 Enter,在完成其它字段後。另外,可以包括字段在 Tab 次序中,但會禁用它。可以啓用它,若它變得閤適,按其它字段在用戶有設置的視圖。
  2. The label for the field can include a keyboard shortcut that moves focus to this field.

Another exception to Tab support is text-entry widgets that must support the insertion of tabs; almost all text editors fall into this class. Qt treats Ctrl+Tab as Tab and Ctrl+Shift+Tab as Shift+Tab , and such widgets can reimplement QWidget::event () and handle Tab before calling QWidget::event () to get normal processing of all other keys. However, since some systems use Ctrl+Tab for other purposes, and many users aren't aware of Ctrl+Tab anyway, this isn't a complete solution.

用戶點擊 Widget

This is perhaps even more common than pressing Tab on computers with a mouse or other pointing device.

Clicking to move the focus is slightly more powerful than Tab . While it moves the focus to a widget, for editor widgets it also moves the text cursor (the widget's internal focus) to the spot where the mouse is clicked.

Since it is so common and people are used to it, it's a good idea to support it for most widgets. However, there is also an important reason to avoid it: you may not want to remove focus from the widget where it was.

For example, in a word processor, when the user clicks the 'B' (bold) tool button, what should happen to the keyboard focus? Should it remain where it was, almost certainly in the editing widget, or should it move to the 'B' button?

We advise supporting click-to-focus for widgets that support text entry, and to avoid it for most widgets where a mouse click has a different effect. (For buttons, we also recommend adding a keyboard shortcut: QAbstractButton and its subclasses make this very easy.)

在 Qt 中,僅 QWidget::setFocusPolicy () 函數影響點擊聚焦。

用戶按下鍵盤快捷鍵

It's not unusual for keyboard shortcuts to move the focus. This can happen implicitly by opening modal dialogs, but also explicitly using focus accelerators such as those provided by QLabel::setBuddy (), QGroupBox ,和 QTabBar .

Your application can support shortcut focus for all widgets that the user may want to jump to. For example, a tab dialog can have keyboard shortcuts for each of its pages, so the user can press e.g. Alt+P to step to the P rinting page. Keep in mind that it's easy to overdo this, as there are only a few keys, and also important to provide keyboard shortcuts for commands. Refer to the design guidelines for the platform you target, for example Microsoft's guidelines for keyboard user interface design or Apple's focus and selection guidelines.

用戶鏇轉鼠標滾輪

On Microsoft Windows, mouse wheel usage is always handled by the widget that has keyboard focus. On macOS and X11, it's handled by the widget that gets other mouse events.

The way Qt handles this platform difference is by letting widgets move the keyboard focus when the wheel is used. With the right focus policy on each widget, applications can work idiomatically correctly on Windows, macOS, and X11.

用戶將焦點移至此窗口

在這種情況下,應用程序必須確定窗口中的哪個 Widget 應接收聚焦。

這可以很簡單:若聚焦前已在此窗口中,那麼,最後一個擁有聚焦的 Widget 應重新獲得聚焦。Qt 會自動做到這。

若聚焦前從未在此窗口中,且知道聚焦應該從哪裏開始,調用 QWidget::setFocus () 在應接收聚焦的 Widget 中,先於調用 QWidget::show () 它。若不,Qt 將拾取閤適 Widget。