Qt:键盘焦点
Posted
技术标签:
【中文标题】Qt:键盘焦点【英文标题】:Qt : keyboard focus 【发布时间】:2012-09-05 13:17:26 【问题描述】:我正在用 Qt 编写一个如下所示的程序:
主窗口是我的类Window : QWidget
,它有一个QGridLayout
,其中包含四个其他小部件(Input_Menu : QWidget
和Output_Menu : QWidget
,然后是两个Canvas : QWidget
)
我想在用户敲击某个键时触发某些事件。问题是,Window
有时会失去焦点(比如Input_Menu
,或者可能是Input_Menu
中的一个按钮...)
我尝试了以下解决方案,但它们似乎并不令人满意(而且很脏):
-
在
Window
失去焦点时为其提供焦点。
告诉每个可能获得焦点的小部件在收到键盘事件时触发Window
的KeyPressEvent
函数(或它的克隆)。
理想情况下,如果一个小部件接收到一个事件(比如键盘事件)并且不知道如何处理它,它应该自动调用其父级的事件处理程序。我希望这是 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实用技巧:将QWidget作为输入窗口,接收键盘消息输入法并且控制输入法悬浮工具栏位置控制