Ebatsin
Ebatsin

Reputation: 581

QWidget UI freezes when using a QQuickWidget

I am working on a software that uses both QQuickWidget and QWidget.

The main window is a QWidget that contains a QQuickWidget used to render stuff with OpenGL.

The QQuickWidget is in a QFrame that is sometimes displayed and sometimes hidden.

The problem is that when the QFrame is hidden, all the UI base on QWidget stops being updated

The weird thing is that only the UI freezes. If you know where to click, the software still work, only the UI is no longer updated. I think it might be that QML steals the rendering loop that is no longer accessible when it is hidden ?

I tested this on : Linux, Qt 5.11.2 : No problem observed Windows 10 64bit, Qt 5.9 : Problem as described above Windows 10 64bit, Qt 5.11.2 : Problem as described above

Below is a small code example that can reproduce the problem. it works this way :

  1. Homescreen is a QWidget. UI is updated on mouse hover (colors change)
  2. on click, it switches to QQuickWidget
  3. QML UI is updated on mouse hover (color change)
  4. on click, it switches back to QWidget
  5. The mouse hover no longer updates the UI (no color change)

main.cpp

#include <QApplication>
#include "myMainWindow.hpp"

int main(int argc, char **argv) {
    QApplication application(argc, argv);

    MyMainWindow window;
    window.show();
    window.raise();

    return application.exec();
}

myMainWindow.hpp

#include <QMainWindow>
#include <QStackedLayout>

class MyMainWindow : public QMainWindow {
    Q_OBJECT

    public:
        explicit MyMainWindow(QWidget *parent = nullptr);
        ~MyMainWindow(void){}

    private:
        QStackedLayout *layout;

    public slots:
        void switchToWidget(void);
};

myMainWindow.cpp

#include <QApplication>
#include <QDebug>
#include <QFrame>
#include <QMainWindow>
#include <QPushButton>
#include <QtQuickWidgets/QQuickWidget>
#include <QQuickItem>
#include <QQmlProperty>

#include "myMainWindow.h"

MyMainWindow::MyMainWindow(QWidget *parent) : QMainWindow(parent) {
    // Central Widget
    QFrame *central = new QFrame;
    central->setFixedSize(300,300);
    this->setCentralWidget(central);

    // BUTTON - QWidget
    QPushButton *buttonWidget = new QPushButton("WIDGET", central);
    buttonWidget->setStyleSheet("QPushButton{"
        "   background-color: red;"
        "}"
        "QPushButton:hover{"
        "   background-color: yellow;"
        "}");

    // BUTTON - QQuickWidget
    QQuickWidget *buttonQML = new QQuickWidget(central);
    buttonQML->setResizeMode(QQuickWidget::SizeRootObjectToView);
    buttonQML->setSource(QUrl("qrc:/qml/ButtonQML.qml"));
    buttonQML->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    // Main Stack Layout
    this->layout = new QStackedLayout(central);
    this->layout->addWidget(buttonWidget);
    this->layout->addWidget(buttonQML);
    this->layout->setCurrentIndex(0);

    // Stack siwtch
    QObject::connect(buttonWidget, &QPushButton::clicked, [=](){
        this->layout->setCurrentIndex(1);
    });

    QQuickItem *rootObject = buttonQML->rootObject();
    QObject::connect(rootObject, SIGNAL(clicked()), this, SLOT(switchToWidget()));
}

void MyMainWindow::switchToWidget(void)  {
    this->layout->setCurrentIndex(0);
}

ButtonQML.qml

import QtQuick 2.0
import QtQuick.Controls 2.1

Button {
    text: "ButtonQML"
    id: root
    background: Rectangle {
        color: root.hovered ? 'green' : 'white'
    }
}

Any idea what could cause this ?

Upvotes: 0

Views: 836

Answers (1)

Ebatsin
Ebatsin

Reputation: 581

I found the problem. Seems that I had not read the QQuickWidget Documentation well enough.

Note: Using QQuickWidget disables the threaded render loop on all platforms. This means that some of the benefits of threaded rendering, for example Animator classes and vsync driven animations, will not be available.

I changed my QQuickWidget to a QQuickView and everything is working.

Upvotes: 0

Related Questions