Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Mouse Tracking not working with QOpenGLWidget as MainWindow's' central widget in Qt 5.12



  • Hey folks, I'm trying to track mouse move events in my GLWidget, which inherits from QOpenGLWidget. I have this widget set as the central widget of my main window. I have NO custom event filters or anything, and the widget correctly receives mouse move events when a mouse button is pressed. I've seen a lot of threads discussing similar issues, but so far no solutions that are relevant for me.

    I am calling setMouseTracking(true); in the constructor of my widget, and am verifying that this is set correctly via hasMouseTracking after setting the widget as the central widget. I don't have any widgets occluding this widget, so I'm really at a loss. I don't want to have to implement my own thread that captures mouse events, since that defeats the point of using Qt.


  • Lifetime Qt Champion

    Hi,

    Which OS ?
    Which version of Qt ?
    Can you provide a minimal compilable example that shows that behaviour ?



  • @SGaist I'm on windows, and I mentioned that I'm using Qt 5.12. I can try to put together a working example, but I'm not doing much besides what I described. My GLWidget looks like this:

    GLWidget.h

    class GLWidget : public QOpenGLWidget, public Object 
    {
        Q_OBJECT
    public:
        //-----------------------------------------------------------------------------------------------------------------
        /// @name Constructors and Destructors
        /// @{
        GLWidget(const QString& name, QWidget *parent);
        ~GLWidget();
        /// @}
    
        //-----------------------------------------------------------------------------------------------------------------
        /// @name Methods
        /// @{
    
        virtual const char* className() const override { return "GLWidget"; }
    
        /// @}
    
        //-----------------------------------------------------------------------------------------------------------------
        /// @name QWidget Overrides
        /// @{
    
        /// @brief Override resize event to send out signal
        virtual void resizeEvent(QResizeEvent* event) override;
    
        /// @}
    signals:
        /// @brief Sent on resize
        void resized(int width, int height);
    
        /// @brief Send on initialization
        void initializedContext();
    
    protected:
        //---------------------------------------------------------------------------------------------
        /// @name Protected Methods
        /// @{
    
        /// @brief Override contextMenuEvent
        void contextMenuEvent(QContextMenuEvent *event) override;
    
        /// @brief Input handlers
        void keyPressEvent(QKeyEvent *event) override;
        void keyReleaseEvent(QKeyEvent *event) override;
        void wheelEvent(QWheelEvent *event) override;
        void mouseDoubleClickEvent(QMouseEvent *event) override;
        void mouseMoveEvent(QMouseEvent *event) override;
        void mousePressEvent(QMouseEvent *event) override;
        void mouseReleaseEvent(QMouseEvent *event) override;
    
        /// @brief GL-specific overrides
    	void initializeGL() override;
    	void resizeGL(int w, int h) override;
    	void paintGL() override;
    
        /// @brief set up signal/slot connections to render manager
        void initializeConnections();
    
        /// @}
    
        // Input handler, processes key and mouse inputs
        InputHandler m_inputHandler;
    
    };
    

    GLWidget.cpp

    GLWidget::GLWidget(const QString& name, QWidget * parent) :
        QOpenGLWidget(parent),
        Object(name), // My own Object class 
        m_inputHandler(this)
    {
        // Initialize all signal/slot connections
        initializeConnections();
    
        // Ensure that mouse is tracked even when button is not clicked
        setMouseTracking(true);
    
        // Ensure that widget accepts keyboard focus
        setFocusPolicy(Qt::StrongFocus);
    }
    /////////////////////////////////////////////////////////////////////////////////////////////
    GLWidget::~GLWidget()
    {
        // Make context current for cleanup
        makeCurrent();
    }
    /////////////////////////////////////////////////////////////////////////////////////////////
    void GLWidget::clear()
    {
        m_renderProjections.clear();
        m_renderer->requestResize();
    }
    /////////////////////////////////////////////////////////////////////////////////////////////
    void GLWidget::resizeEvent(QResizeEvent * event)
    {
        // Perform base class resize event
        QOpenGLWidget::resizeEvent(event);
    
        // Emit resize signal (connects to RenderProjection class)
        emit resized(width(), height());
    
    #ifdef DEBUG_MODE
        //int w = width();
        //int h = height();
    #endif
    }
    /////////////////////////////////////////////////////////////////////////////////////////////
    void GLWidget::initializeGL()
    {
    	// Needed to checkValidity GL
    	m_renderer = std::make_shared<MainRenderer>(m_engine, this);
    	m_renderer->initialize();
    
        // Emit signal that GL context is initialized
        emit initializedContext();
    }
    /////////////////////////////////////////////////////////////////////////////////////////////
    void GLWidget::resizeGL(int w, int h)
    {
        Q_UNUSED(w);
        Q_UNUSED(h);
        resizeProjections(w, h);
        if (m_engine->scenario()) {
            m_renderer->requestResize();
            m_renderer->render();
        }
    }
    /////////////////////////////////////////////////////////////////////////////////////////////
    void GLWidget::paintGL()
    {
        if (m_engine->scenario()) {
            // This is called from the main simloop's update routine (GLWidget::update())
            // TODO: Separate processScenes and render logic into different loops
            m_renderer->processScenes(); 
            m_renderer->render();
        }
    }
    
    void GLWidget::keyPressEvent(QKeyEvent * event)
    {
        m_inputHandler.handleEvent(event);
        QOpenGLWidget::keyPressEvent(event);
    }
    
    void GLWidget::keyReleaseEvent(QKeyEvent * event)
    {
        m_inputHandler.handleEvent(event);
        QOpenGLWidget::keyReleaseEvent(event);
    }
    
    void GLWidget::wheelEvent(QWheelEvent * event)
    {
        m_inputHandler.handleEvent(event);
        QOpenGLWidget::wheelEvent(event);
    }
    
    void GLWidget::mouseDoubleClickEvent(QMouseEvent * event)
    {
        m_inputHandler.handleEvent(event);
        //QOpenGLWidget::mouseDoubleClickEvent(event); // Don't send another press event
    }
    
    void GLWidget::mouseMoveEvent(QMouseEvent * event)
    {
        m_inputHandler.handleEvent(event);
        //event->ignore();
        QOpenGLWidget::mouseMoveEvent(event);
    }
    
    void GLWidget::mousePressEvent(QMouseEvent * event)
    {
        m_inputHandler.handleEvent(event);
        QOpenGLWidget::mousePressEvent(event);
    }
    
    void GLWidget::mouseReleaseEvent(QMouseEvent * event)
    {
        m_inputHandler.handleEvent(event);
        QOpenGLWidget::mouseReleaseEvent(event);
    }
    
    void GLWidget::initializeConnections()
    {
        connect(m_engine, &CoreEngine::scenarioNeedsRedraw, this, static_cast<void (GLWidget::*)()>(&GLWidget::resizeProjections));
    }
    
    
    

  • Lifetime Qt Champion

    @feistykittykat said in Mouse Tracking not working with QOpenGLWidget as MainWindow's' central widget in Qt 5.12:

    and I mentioned that I'm using Qt 5.12.

    Not in this thread.

    That class does not show anything obviously wrong hoe we there are missing pieces like the custom input handler that does not allow to guess what might be happening.


Log in to reply