简体   繁体   中英

Qt Quick very slow painting

I have just started to look at Qt Quick and I have a very basic program, essentially the same as when you start a Qt Quick Controls application project.

The problem is when I try to resize the window it takes a very long time to do so. This can be seen in the .gif below.

问题

The only information I could find on the web about people having a similar problem was that you could use the QML Profiler to find where the lag is being generated and sometimes it is due to the debugger. So below you can see the QML profiler and the gif was recorded in release mode.

在此输入图像描述

As far as I can tell the animation is locking the GUI thread up which is causing the render or repainting to be slow but I am not sure what is causing it.

I would appreciate any help in solving the problem.

And there is not much code to it.

Test.pro

QT += qml quick
CONFIG += c++11
SOURCES += main.cpp
RESOURCES += qml.qrc
QML_IMPORT_PATH =
QML_DESIGNER_IMPORT_PATH =
DEFINES += QT_DEPRECATED_WARNINGS
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    SwipeView {
        id: swipeView
        anchors.fill: parent
        currentIndex: tabBar.currentIndex

        Page1 {
            Label {
                text: qsTr("First page")
                anchors.centerIn: parent
            }
        }

        Page {
            Label {
                text: qsTr("Second page")
                anchors.centerIn: parent
            }
        }

        Page {
            Label {
                text: qsTr("Third page")
                anchors.centerIn: parent
            }
        }
    }

    footer: TabBar {
        id: tabBar
        currentIndex: swipeView.currentIndex
        TabButton {
            text: qsTr("First")
        }
        TabButton {
            text: qsTr("Second")
        }
        TabButton {
            text: qsTr("Third")
        }
    }
}

Page1.qml

import QtQuick 2.7

Page1Form {
    button1.onClicked: {
        console.log("Button Pressed. Entered text: " + textField1.text);
    }
}

Page1Form.ui.qml

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

Item {
    property alias textField1: textField1
    property alias button1: button1

    RowLayout {
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.topMargin: 20
        anchors.top: parent.top

        TextField {
            id: textField1
            placeholderText: qsTr("Text")
        }

        Button {
            id: button1
            text: qsTr("Press Me")
        }
    }
}

Specs: Windows 10, Qt 5.9, MSVC 2017


Qt Forum Cross Post

Recently this Qt Bug was fixed, since 5.9.2: https://bugreports.qt.io/browse/QTBUG-59893

Does this fix solve this issue?

I think you have this issue because software rendering is used under the hood. So it takes pretty long. So to enable hardware rendering, you need to install ANGLE drivers. Your profiling picture states that swap operation is taking all the time, so this is actually copying all the pixels from CPU to GPU, so that is why you see this lag. I don't agree with @dtech that it wont help you. I used ANGLE drivers for rendering pretty complex GL 3D scenes on Windows, so QT is capable of that, I am sure

On a window resize qml has to reevaluate the bindings for size. So everything that changed size or has anchor properties needs to be recalculated. As far as i know QT uses openGL as default renderer. On a window resize the buffer openGL renders to needs to be resized aswell and the complete scenegraph needs to be repainted. But before that happens the single elements need to be rerendered first if their size changed. Qml stores visible elements in textures so as elements resize textures have to be recreated...

Probably there is even more happening depending on what elements you use or how your scenegraph is build or how your batches are composed.

If you want to debug the scenegraph you can do so by setting enviroment vars. For example you can make changes flash in random colors by setting

QSG_VISUALIZE=changes

More info about Qt Quick Scene Graph Renderer here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM