Qt 5.0: QQuickView blocks GUI thread
-
When forcing the QQuickView to update at 60Hz or faster, the main GUI thread blocks. Resizing and moving the window no longer works.
Connecting the beforeRendering() signal to a function that prints the current thread (using DirectConnection) shows that the rendering is not taking place in a separate rendering thread, unlike the documentation suggests.Problem: Why is the QQuickView not doing the rendering in a separate thread, as the docs suggest it would?
The code below shows the problem. The timer forces the QQuickView to update at 100Hz (which is limited to 60Hz, as can be seen in the qDebug() messages).
The code also shows that, were you to disable the timer and trigger the infinite animation by clicking the contents, it will also start updating at 60Hz, and block the main GUI thread.Both forced updates and Qml animations block the main GUI thread.
main.cpp:
@
#include <QtGui>
#include <QtOpenGL>
#include <QtQuick>#include "myobject.h"
int main(int argc, char** argv)
{
QGuiApplication app(argc, argv);qDebug() << QThread::currentThread(); QQuickView view(QUrl("main.qml")); QObject::connect(view.engine(), SIGNAL(quit()), &view, SLOT(close())); view.show(); MyObject obj; QObject::connect(&view, SIGNAL(beforeRendering()), &obj, SLOT(notify()), Qt::DirectConnection); QTimer timer; QObject::connect(&timer, SIGNAL(timeout()), &view, SLOT(update())); timer.start(10); app.exec();
}
@myobject.h:
@
#pragma once
#include <QtGui>class MyObject : public QObject
{
Q_OBJECTpublic slots:
void notify()
{
qDebug() << QThread::currentThread() << time.nsecsElapsed();
time.restart();
}private:
QElapsedTimer time;
};
@main.qml:
@
import QtQuick 2.0Rectangle {
width: 360
height: 360
Text {
id: text
text: qsTr("Hello World")
x: 50
y: 180NumberAnimation { id: ani loops: Animation.Infinite target: text property: "x" duration: 200 easing.type: Easing.InOutQuad from: 50 to: 250 } } MouseArea { anchors.fill: parent onClicked: { ani.start() } }
}
@