Search code examples
c++qtevent-handlingmouseeventqt3d

QObjectPicker not receiving hovering QMouseEvent in Qt3DWidget


I've implemented a Qt3DWidget which works fairly well by letting Qt3D draw to an offscreen texture and using the texture's ID to draw on a quad in a QOpenGLWidget. The input source on the QInputSettings is set to this, i.e. the widget itself.

One issue that remains is that mouse hovering events (without clicking) are not properly processed and a QObjectPicker never fires its moved event when only hovering over an object. Clicking and dragging works on the other hand. For a couple of hours now I tried to track down where the event gets eaten - I'm sure this happens somewhere because clicking and moving emits the moved event. The latter indicates (in my view) that the event filter (a PickEventFilter - private Qt3D class) has been successfully installed. One failure case would have been that the event filter doesn't get installed.

Now I'm kind of stuck because it just seems impossible trying to figure out where the event dies. I've got the Qt debugging symbols and stepped through the code (which is sometimes a bit buggy because maybe due to code optimization). I figured out that the PickEventFilter gets the leaving event when moving the mouse by setting a breakpoint in this method:

bool PickEventFilter::eventFilter(QObject *obj, QEvent *e)
{
    Q_UNUSED(obj);
    switch (e->type()) {
    case QEvent::MouseButtonPress:
    case QEvent::MouseButtonRelease:
    case QEvent::MouseMove: {
        QMutexLocker locker(&m_mutex);
        m_pendingMouseEvents.push_back({obj, QMouseEvent(*static_cast<QMouseEvent *>(e))});
    } break;
    case QEvent::HoverMove: {
        QMutexLocker locker(&m_mutex);
        QHoverEvent *he = static_cast<QHoverEvent *>(e);
        m_pendingMouseEvents.push_back({obj, QMouseEvent(QEvent::MouseMove,
                                                   he->pos(), Qt::NoButton, Qt::NoButton,
                                                   he->modifiers())});
    } break;
    case QEvent::KeyPress:
    case QEvent::KeyRelease: {
        QMutexLocker locker(&m_mutex);
        m_pendingKeyEvents.push_back(QKeyEvent(*static_cast<QKeyEvent *>(e)));
    }
    default:
        break;
    }
    return false;
}

And also on this line in QWidgetWindow:

    QApplicationPrivate::sendMouseEvent(receiver, &translated, widget, m_widget,
                                        &qt_button_down, qt_last_mouse_receiver);

When sendMouseEvent sends the moving event it never reaches the event filter. The only thing that arrives is a leave event. When you use createWindowContainer and Qt3DWindow the mouse events work. I really don't know what the difference is.

I don't think it's feasible to post code related to this issue but I'd hope that some of you can provide some ideas what to try out.


Solution

  • Thanks to Scheff in the comments I was able to make it work by setting setMouseTracking in the QWidget class to true. This was blocking the hovering events.