QWidget 似乎忽略了 EventFilter 传递的事件
Posted
技术标签:
【中文标题】QWidget 似乎忽略了 EventFilter 传递的事件【英文标题】:QWidget seems to ignore event passed by 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
【参考方案1】:
当您调用QApplication::sendEvent(widget, event);
并且如果widget
是MainWindow
或其自身的孩子,接收事件将在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;
。
很高兴听到这个消息!以上是关于QWidget 似乎忽略了 EventFilter 传递的事件的主要内容,如果未能解决你的问题,请参考以下文章
QTableView 中 Drop-Events 的 EventFilter
accept()函数用来告诉Qt,事件处理函数“接收”了这个事件,不要再传递;ignore()函数则告诉Qt,事件处理函数“忽略”了这个事件,需要继续传递(看一下QWidget::mousePress