确定 QKeyEvent 的来源

Posted

技术标签:

【中文标题】确定 QKeyEvent 的来源【英文标题】:Determine source of QKeyEvent 【发布时间】:2014-09-22 18:57:44 【问题描述】:

我有一个Qt 应用程序,其中包含多个同时显示按钮的小部件。在某些情况下,我希望将按键发送到其中一个小部件,即使该小部件没有焦点。为此,我在主小部件(拥有此应用程序中的所有子小部件)中覆盖了keyPressEvent(),如果它没有焦点,则使用类似于此的代码将键事件重新发送到子小部件:

if (!someWidget->hasFocus())

    QApplication::sendEvent(someWidget, keyEvent);

只要someWidgethandes 表示事件,这将非常有效。如果它忽略它,那么它会进入一个讨厌的无限递归循环,因为事件会流向父母。

有没有办法知道事件来自哪里,这样我就可以防止这种无限循环?我正在考虑这样的事情:

if (!someWidget->hasFocus() && (keyEvent->source != someWidget))

    QApplication::sendEvent(someWidget, keyEvent);

或者有其他方法可以防止这种情况发生吗?

【问题讨论】:

QApplication::focusWidget?恕我直言,QKeyEvent 的来源是用户 -> 平台 API。 【参考方案1】:

当您使用信号和插槽机制时,您可以调用sender(),它可以为您提供信息,但接下来您可以执行以下操作:使用eventFilter,它可以为您提供有关每个QObject 的信息,它将事件发送到mainWindow ,因此您可以捕获事件和发送者

    bool MainWindow::eventFilter(QObject *obj, QEvent *event)
    
    if(event->type() == QEvent::KeyPress)//your keyPressEvent but with eventFilter
        if(!someWidget->hasFocus() && obj != someWidget)//your focus and source checkings, obj is object which send some event,
                                                        // but eventFilter catch it and you can do something with this info
           
        //do something, post event
        

return QObject::eventFilter(obj, event);

别忘了

protected:
     bool eventFilter(QObject *obj, QEvent *event);

也许你需要使用QKeyEvent,所以如果你确定event->type() == QEvent::KeyPress,请转换QEvent。例如:

QKeyEvent *key = static_cast<QKeyEvent*>(event);
if(key->key() == Qt::Key_0)

    //do something

【讨论】:

在 eventFilter(QObject *obj, QEvent *event) 中,'obj' 是被监视的对象,而不是发送事件的对象。你知道是否有办法确定事件起源吗? @KyleL 是什么情况?您选择何时执行此操作还是用户操作?也许你可以用信号槽做到这一点并使用 sender() @KyleL 你想做什么?抓住按下并将文本设置为其他文本编辑或什么?

以上是关于确定 QKeyEvent 的来源的主要内容,如果未能解决你的问题,请参考以下文章

QWidget QLabel没有响应keyEvent键盘事件

Qt 制表符顺序键

怎样模拟发送key event按键消息和touch event触摸消息?

按键事件错误

public boolean onKeyDown(int keyCode, KeyEvent event)

拦截 Tab 按键以手动管理焦点切换