本页内容

控件中的键盘焦点

Qt Widgets 处理键盘焦点的机制已符合图形用户界面(GUI)的惯例。

基本问题在于,用户的按键操作可能指向屏幕上的多个窗口中的任意一个,以及目标窗口内的多个控件中的任意一个。当用户按下键时,他们期望按键能到达正确的位置,而软件必须尽力满足这一期望。 系统必须确定按键操作指向的是哪个应用程序、该应用程序中的哪个窗口,以及该窗口中的哪个控件。

焦点移动

关于将键盘焦点引导至特定控件,已形成以下惯例:

  1. 用户按下Tab (或Shift+Tab )。
  2. 用户单击一个控件。
  3. 用户按下键盘快捷键。
  4. 用户使用鼠标滚轮。
  5. 用户将焦点移至某个窗口,此时应用程序必须确定该窗口内的哪个控件应获得焦点。

这些操作机制各不相同,不同类型的控件仅在其中某些机制下才会获得焦点。我们将依次介绍每种机制。

Tab 或 Shift+Tab

按下Tab 是迄今为止使用键盘移动焦点的最常见方式。(有时在数据输入应用程序中,Enter键的作用与Tab 相同;在Qt中,通过实现一个事件过滤器即可轻松实现这一点。)

在当今所有常用窗口系统中,按下Tab 会将键盘焦点移至窗口内循环列表中的下一个控件。Tab 使焦点沿循环列表向一个方向移动,Shift+Tab 则向相反方向移动。按下Tab 时焦点在控件间移动的顺序称为“Tab 顺序”。

您可以使用QWidget::setTabOrder() 自定义 Tab 顺序。(若不进行自定义,Tab 通常会按控件创建的顺序移动焦点。)Qt Widgets Designer 提供了一种通过视觉方式更改 Tab 顺序的方法。

由于按下Tab 非常常见,因此大多数可以获得焦点的控件都应支持Tab焦点。主要例外情况是那些很少使用的控件,以及存在某些键盘快捷键或错误处理程序会移动焦点的控件。

例如,在数据输入对话框中,可能存在一个仅在 1% 的情况下才需要的字段。在此类对话框中,Tab 可能会跳过该字段,此时对话框可采用以下机制之一:

  1. 如果程序能够判断该字段是否必要,则可在用户完成输入并按下OK 键时,或在用户完成其他字段输入后按下Enter键时,将焦点移至该字段。或者,将该字段纳入Tab键焦点顺序中但将其禁用。当根据用户在其他字段中的设置判断该字段变得必要时,再将其启用。
  2. 该字段的标签中可以包含一个将焦点移至该字段的键盘快捷键。

对Tab 支持的另一例外是必须支持插入制表符的文本输入控件;几乎所有文本编辑器都属于这一类。 Qt 将Ctrl+Tab 视为Tab ,将Ctrl+Shift+Tab 视为Shift+Tab ,此类控件可以重写QWidget::event() 方法,在调用QWidget::event() 之前处理 Tab 键,从而使所有其他键获得正常处理。但是,由于某些系统将Ctrl+Tab 用于其他用途,而且许多用户根本不知道Ctrl+Tab 的存在,因此这并非一个完整的解决方案。

用户点击控件

在配备鼠标或其他指针设备的计算机上,这种情况可能比按下Tab 更为常见。

点击来移动焦点比Tab 稍强一些。虽然它会将焦点移至某个控件,但对于编辑器控件而言,它还会将文本光标(即控件的内部焦点)移至鼠标点击的位置。

由于这种操作非常普遍且用户已习惯,因此为大多数控件支持该功能是个好主意。然而,也有一个重要的理由需要避免这样做:您可能不希望将焦点从原控件上移开。

例如,在文字处理软件中,当用户点击“B”(加粗)工具按钮时,键盘焦点应该如何处理?是保持原位(几乎肯定是在编辑控件中),还是移至“B”按钮?

我们建议对支持文本输入的小部件支持“点击获得焦点”功能,而对于大多数鼠标点击会产生不同效果的小部件,则应避免使用该功能。(对于按钮,我们还建议添加键盘快捷键:QAbstractButton 及其子类可以非常轻松地实现这一点。)

在 Qt XML 中,只有 `QWidget::setFocusPolicy()` 函数会影响“点击获得焦点”行为。

用户按下键盘快捷键

键盘快捷键移动焦点的情况并不少见。这既可能通过打开模态对话框隐式发生,也可能通过显式使用焦点加速器实现,例如由QLabel::setBuddy()、QGroupBox 和QTabBar 提供的功能。

您的应用程序可以为所有用户可能希望跳转到的控件支持快捷键焦点。例如,一个标签页对话框可以为其每个页面设置键盘快捷键,这样用户就可以按Alt+P 跳转到“打印”页面。 请注意,由于可用键位有限,很容易在这方面做得过头;同时,为各项命令提供键盘快捷键也至关重要。请参考您目标平台的设计指南,例如微软的键盘用户界面设计指南或苹果的焦点与选择指南。

用户滚动鼠标滚轮

在 Microsoft Windows 上,鼠标滚轮的操作始终由拥有键盘焦点的控件处理。而在 macOS 和 X11 上,则由接收其他鼠标事件的控件处理。

Qt 通过让控件在滚轮被使用时移动键盘焦点来处理这种平台差异。只要为每个控件设置正确的焦点策略,应用程序就能在 Windows、macOS 和 X11 上以符合惯例的方式正确运行。

用户将焦点移至此窗口

在此情况下,应用程序必须确定窗口内的哪个控件应获得焦点。

这可能很简单:如果焦点之前曾在此窗口中,则最后获得焦点的控件应重新获得焦点。Qt 会自动完成此操作。

如果焦点从未进入过此窗口,且您知道焦点应从何处开始,请在调用 `QWidget::show()` 之前,先对应接收焦点的控件调用 `QWidget::setFocus()`。若不这样做,Qt 将自动选择一个合适的控件。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.