Congratulations to our 2022 Qt Champions!

QGraphicsWidget not receiving wheelEvent()

  • I have a QGraphicsWidget that I'm trying to get to accept wheel events, but every wheelEvent() goes instead to the parent QGraphicsView.

    The following all work as expected:

    virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
    virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
    virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
    virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
    virtual void keyPressEvent(QKeyEvent *event);

    But for whatever reason, the following never fires on my QGraphicsWidget:

    virtual void wheelEvent(QGraphicsSceneWheelEvent *event);

    I've tried the following with no success:

    setFlag(QGraphicsItem::ItemIsFocusable, true);

    I'd open to suggestions. Thanks!

  • I'm a bit confused here. You mentioned that the "parent" QGraphicsView was catching the signals, but QGraphicsWidget is not derived from QGraphicsView at all.

    If you mean you have a QGraphicsView and as a child of that a QGraphicsWidget then my guess is to make sure your QGraphicsView does not take the event.

    You can force the event to be ignored by your QGraphicsView. See the documentation for QEvent. That should make sure you get the event in your widget.

    I may be completely misunderstanding the problem though.

  • Sorry, I was being loose with terminology. What I meant was that the QGraphicsView displaying the QGraphicsScene containing my widget is getting the wheelEvent() instead of my widget.

    I do need the QGraphicsView to handle wheelEvent() at times because I'm using the mouse wheel to scroll & zoom the view. But when my widget is active (and displaying a drop down list) I want to be able to capture wheelEvent() so I can, for example, scroll the drop down list.

    I'm finding that, except for wheelEvent(), all the other mouse events are (as I would expect) sent to my widget so I can handle them before the view sees them. Does that make sense?

  • @AaronC Yea that makes a lot more sense.. Can I see the code for the wheelEvent handlers in both classes?

    Also what happens if you stop grabbing wheel events in your graphicsview, just to test. Make sure it works in the widget when you comment out that function. Help eliminate possible issues.

  • For my QGraphicsView:

    void CustomGraphicsView::wheelEvent(QWheelEvent *event)
        if (event->modifiers().testFlag(Qt::ControlModifier))
            pi->zooming = true;
            qreal deltaZoom = (qreal) event->angleDelta().y();
            emit zoom(event->globalPosF(), deltaZoom);
            // Allow vertical scrolling
            emit verticalScroll(event->globalPosF(), event->angleDelta().y());
            // Allow horizontal scrolling, if enabled
            if (pi->horizontalScrollingEnabled)
                emit horizontalScroll(event->globalPosF(), event->angleDelta().x());

    And in my widget, I'm not doing anything yet, just trying to log events:

    void CustomGraphicsWidget::wheelEvent(QGraphicsSceneWheelEvent */*event*/)
        qDebug() << Q_FUNC_INFO;

    Now that I'm looking at this with fresh eyes I see that these are two different events. The view is receiving a QWheelEvent* and the widget a QGraphicsSceneWheelEvent*. Maybe I need to enable wheel events in the QGraphicsScene? I'll take a look.

  • I did find just now that commenting out CustomGraphicsView::wheelEvent() does allow the event to be passed to my QGraphicsWidget. Any ideas on how to give precedence for wheelEvents to my widget instead of the graphics view?

  • @AaronC Hmm this might be happening because the QGraphicsWidget does not have a focus. So the first one in the group it's in gets the wheel event.

    If the focus thing doesn't pan out maybe you could look for children of the graphics view, give them the wheel event and if they don't handle it, finally handle it in the graphics view.

    I'm not sure if that is a good solution though, but I haven't worked with the graphicsview/widget enough to know another way.

  • Moderators

    I'd try something like this:

    void CustomGraphicsView::wheelEvent(QWheelEvent *event)
        if (event->accepted())
        // Rest of code

  • That works great. It also made me review how I was scrolling the scene and now have a cleaner design. Thanks!

Log in to reply