【问题标题】:QWidget seems to ignore event passed by EventFilterQWidget 似乎忽略了 EventFilter 传递的事件
【发布时间】:2018-06-27 10:00:02
【问题描述】:

我在尝试使用 QT eventFilter 传递事件时遇到问题。

bool MainWindow::eventFilter(QObject *obj, QEvent *event){
if(event->type() == QEvent::Wheel){
    QPoint pos = QCursor::pos();
    QWidget *widget = QApplication::widgetAt(pos);
        if(widget != NULL){
            widget->setVisible(false); //for Test purposes only
            qDebug() << widget; //also for test 
            QApplication::sendEvent(widget, event); //should send event to widget?
                return true;
            }

                return true;
        }
    return false;
}

我想捕捉鼠标滚轮的滚动并将其一次传递给多个 QWidget。如果我在没有 sendEvent 的情况下执行上述操作,我想参加的小部件将消失(这就是我想要的测试)。如果我使用 sendEvent,什么都不会发生,或者它会因分段错误错误而崩溃……我尝试了我在网上找到的任何东西(或者我至少是这么认为的)..

提前致谢!!!

【问题讨论】:

  • 如果您将事件发送到小部件,您将最终陷入无限递归,因为事件过滤器会再次拦截它。如果您希望小部件接收事件,只需返回 false,如果您想停止事件传播,请返回 true

标签: qt qt5


【解决方案1】:

当您调用QApplication::sendEvent(widget, event); 并且如果widgetMainWindow 或其自身的孩子,接收事件将在MainWindow::eventFilter 中再次过滤。它创建了一个递归无限循环。 如果事件正在发送,我向return true; 添加了一个标志sendingEvent。希望能有所帮助。

bool MyWindow::eventFilter(QObject *obj, QEvent *event){

    if (event->type() == QEvent::Wheel)
    {
        static bool sendingEvent = false;
        if (sendingEvent)
        {
            //exit recursive call, return false to avoid swallowing the event
            return false;
        }
        QPoint pos = QCursor::pos();
        QWidget *widget = QApplication::widgetAt(pos);
        if (widget != NULL){
            qDebug() << widget; //also for test         

            //set the flag before sending event
            sendingEvent = true;

            QApplication::sendEvent(widget, event); //should send event to widget?

            //reset the flag after sending event
            sendingEvent = false;
            return true;
        }
        return true;
    }
    return false;
}

【讨论】:

  • 非常感谢!我已经想知道为什么 qDebug 输出列出了这么多项目。我也猜想这将解决崩溃!但是该事件似乎仍然没有传递给小部件......这是一个 QCustomPlot 应该在滚动时放大。 (当我在事件过滤器中直接返回 false 时它确实有效,因此在小部件站点上处理事件应该不是问题)。
  • 对不起,我返回 true 以退出递归调用,因为它吞下了事件。已更新为 return false;
  • 很高兴听到这个消息!
猜你喜欢
  • 2021-10-28
  • 2016-09-30
  • 2016-03-16
  • 2014-02-03
  • 2012-03-11
  • 2013-09-07
  • 2016-08-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多