Qt:键盘焦点

Posted

技术标签:

【中文标题】Qt:键盘焦点【英文标题】:Qt : keyboard focus 【发布时间】:2012-09-05 13:17:26 【问题描述】:

我正在用 Qt 编写一个如下所示的程序:

主窗口是我的类Window : QWidget,它有一个QGridLayout,其中包含四个其他小部件(Input_Menu : QWidgetOutput_Menu : QWidget,然后是两个Canvas : QWidget

我想在用户敲击某个键时触发某些事件。问题是,Window 有时会失去焦点(比如Input_Menu,或者可能是Input_Menu 中的一个按钮...)

我尝试了以下解决方案,但它们似乎并不令人满意(而且很脏):

    Window 失去焦点时为其提供焦点。 告诉每个可能获得焦点的小部件在收到键盘事件时触发WindowKeyPressEvent 函数(或它的克隆)。

理想情况下,如果一个小部件接收到一个事件(比如键盘事件)并且不知道如何处理它,它应该自动调用其父级的事件处理程序。我希望这是 Qt 的默认功能,但它看起来不像。另一方面,我对整个焦点问题感到非常困惑,我真的不明白发生了什么。有人可以向我解释一下吗:我在Window::KeyPressEvent 函数中包含了一个std::cout << "key pressed" << std::endl;。当我第一次运行我的程序时,似乎焦点在Input_Menu 中的顶部 QComboBox 上:如果我按下向上/向下键,我会在该框中导航并且在我的控制台中没有显示“按下键”。如果我击中大多数字母,则不会发生任何事情。但是,如果我按左/右键,我的控制台中会出现“按下键”!?

非常感谢您的见解。

【问题讨论】:

【参考方案1】:

您可以在QApplication 上安装事件过滤器,以全局过滤相关的QEvent::KeyPress 事件。来自 Qt 文档:

还可以过滤整个应用程序的所有事件, 通过在 QApplication 或 QCoreApplication 上安装事件过滤器 目的。这样的全局事件过滤器在 特定于对象的过滤器。这是非常强大的,但它也会减慢 整个应用程序中每个事件的事件传递;这 通常应使用所讨论的其他技术。

除了性能方面的考虑之外,请记住在过滤键事件之前检查您的窗口当前是否具有焦点,否则您可能会破坏弹出对话框或输入到其他窗口。

【讨论】:

感谢您的回答,这很有趣,但不幸的是,在我的具体情况下,我不想这样做。【参考方案2】:

其实我发现对于修饰符的键(比如Shift、Control),Qt支持判断是否被按下。

例如:if(QApplication::keyboardModifiers() == Qt::ShiftModifier) ...

这就够了。

【讨论】:

以上是关于Qt:键盘焦点的主要内容,如果未能解决你的问题,请参考以下文章

Qt中的键盘事件,以及焦点的设置(比较详细)

仅由 UDLR 按钮操作的虚拟键盘的 Qt 焦点处理

Qt的焦点策略

Qt实用技巧:将QWidget作为输入窗口,接收键盘消息输入法并且控制输入法悬浮工具栏位置控制

QWidget 键盘事件 焦点(QApplication源码)

qt焦点左右键切换问题,求大神指导!!