Passing QWheelEvents to child causes infinite loop
-
I have a container QWidget which can contain another input widget (combobox, slider, spinbox, etc) which is receiving QWheelEvents and it needs to pass these QWheelEvents on to the child widget to interpret (i.e. to change the value in the spinbox). I have done this by overriding QWidget::wheelEvent(QWheelEvent* event).
void MyWidget::wheelEvent(QWheelEvent* event) { QApplication::sendEvent(childWidget, event); }
However, if for some reason the child widget cannot accept the wheel event (such as it is disabled) the QWheelEvent is passed back to the parent object creating an infinite loop.
The original QWheelEvent is being synthesized from an event filter in the QApplication and sent using
//Using Qt 5.6.3 QWheelEvent wheelEvent = QWheelEvent(widgetInFocus->pos(), widgetInFocus->mapToGlobal(widgetInFocus->pos()), QPoint(0,0), QPoint(0,120), 120, Qt::Vertical, Qt::NoButton, Qt::NoModifier, Qt::ScrollEnd, Qt::MouseEventSynthesizedByApplication); QApplication::sendEvent(widgetInFocus, wheelEvent)
I also can't send the wheelEvent directly to the child object because there is no way of accessing it in the QApplication event filter because the QApplication does not know if
widgetInFocus
is a MyWidget object or not.Is there a way I can prevent this infinite loop?
-
Apart from the question why a subwidget should get such an event when it doesn't have the focus - simply remember the event in MyWidget::event() and when it's coming again don't call sendEvent()
-
Then create a copy, send this and remember this pointer.
-
@PhabSeals said in Passing QWheelEvents to child causes infinite loop:
wheelEvent(QWheelEvent* event)
if wheelEvent(QWheelEvent* event) is not overridden in the child class of MyWidget, QApplication::sendEvent(widgetInFocus, wheelEvent) basically will call void MyWidget::wheelEvent(QWheelEvent* event) again and this is an infinite loop.
Also you need to check at least
if ( MyWidget pointer( or this) != widgetInFocus ) {
QApplication::sendEvent(widgetInFocus, wheelEvent)
}
if MyWidget pointer(or this) is in focus, your code is also doomed. This can happen often on touch screen while the focus widget is not the one you expect. -
@PhabSeals said in Passing QWheelEvents to child causes infinite loop:
I also can't send the wheelEvent directly to the child object because there is no way of accessing it in the QApplication event filter because the QApplication does not know if
widgetInFocus
is a MyWidget object or not.Presuming that MyWidget is registered with the metaobject system, ie uses Q_OBJECT, either of the following will resolve this question:
!strcmp(widgetInFocus->staticMetaObject().className(), "MyWidget"); qobject_cast<MyWidget *>(widgetInFocus) != nullptr;