Qt Quick очень медленно рисует

Я только начал изучать Qt Quick, и у меня есть очень простая программа, по существу такая же, как когда вы запускаете проект приложения Qt Quick Controls.

Проблема в том, что когда я пытаюсь изменить размер окна, это занимает очень много времени. Это можно увидеть на .gif ниже.

Проблема

Единственная информация, которую я смог найти в Интернете о людях, имеющих аналогичную проблему, заключалась в том, что вы можете использовать QML Profiler, чтобы найти, где генерируется отставание, а иногда это связано с отладчиком. Итак, ниже вы можете увидеть профилировщик QML, а gif был записан в режиме релиза.

введите здесь описание изображения

Насколько я могу судить, анимация блокирует поток графического интерфейса, что приводит к замедлению рендеринга или перерисовки, но я не уверен, что вызывает это.

Буду признателен за любую помощь в решении проблемы.

И там не так много кода.

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")
        }
    }
}

Спецификации: Windows 10, Qt 5.9, MSVC 2017


Перекрестная публикация форума Qt


person Dan    schedule 18.07.2017    source источник
comment
У меня нет таких проблем, как у тебя. Размер окна изменяется очень плавно. Возможно, вам придется перепроверить другие вещи. Я использую Qt5.9 и Visual Studio 2015.   -  person CroCo    schedule 19.07.2017
comment
@КроКо Хорошо. Спасибо. Это странно. Интересно, могла ли на это повлиять версия Visual Studio?   -  person Dan    schedule 19.07.2017
comment
Не уверен, но функция изменения размера окна — обычное дело. Я сомневаюсь, что QML не поддерживает эту функцию. Более того, приложение, которое вы используете, очень простое, даже очень простой API не будет иметь этого симптома. Что-то не так происходит.   -  person CroCo    schedule 19.07.2017


Ответы (3)


Недавно эта ошибка Qt была исправлена, начиная с версии 5.9.2: https://bugreports.qt.io/browse/QTBUG-59893

Это исправление решает эту проблему?

person Bartel    schedule 19.10.2017
comment
Спасибо за ваш ответ. Я обязательно займусь этим, когда вернусь с работы - person Dan; 19.10.2017
comment
К сожалению, это, похоже, не сработало для меня. Однако это может быть связано с тем, что мои настройки неверны. Знаете ли вы, как сделать проект ANGLE или D3D9 поверх проекта по умолчанию, который, по-видимому, является проектом D3D11? - person Dan; 29.10.2017

Я думаю, у вас есть эта проблема, потому что под капотом используется программный рендеринг. Так что это занимает довольно много времени. Поэтому, чтобы включить аппаратный рендеринг, вам необходимо установить драйверы ANGLE. На вашем изображении профилирования указано, что операция подкачки выполняется постоянно, поэтому на самом деле происходит копирование всех пикселей из ЦП в ГП, поэтому вы видите эту задержку. Я не согласен с @dtech, что это вам не поможет. Я использовал драйверы ANGLE для рендеринга довольно сложных 3D-сцен GL в Windows, так что QT на это способен, я уверен.

person rightaway717    schedule 20.07.2017

При изменении размера окна qml должен переоценить привязки по размеру. Так что все, что изменило размер или имеет свойства привязки, нужно пересчитывать. Насколько я знаю, QT использует openGL в качестве рендерера по умолчанию. При изменении размера окна буфер рендеринга OpenGL также должен быть изменен, а весь график сцены должен быть перерисован. Но прежде чем это произойдет, отдельные элементы должны быть перерисованы, если их размер изменился. Qml хранит видимые элементы в текстурах, поэтому при изменении размера элементов текстуры необходимо воссоздавать...

Вероятно, происходит еще больше в зависимости от того, какие элементы вы используете, как построен ваш график сцены или как составлены ваши пакеты.

Если вы хотите отладить график сцены, вы можете сделать это, установив переменные среды. Например, вы можете сделать так, чтобы изменения мигали случайными цветами, установив

QSG_VISUALIZE=changes

Дополнительная информация о Qt Quick Scene Graph Renderer здесь.

person SigSegOwl    schedule 18.07.2017
comment
Хорошо. Итак, вы знаете, как я могу ускорить процесс? - person Dan; 19.07.2017
comment
Звучит глупо, но не изменяйте размер окна и не используйте элементы с динамическим размером. кроме этого, я еще не нашел решения для этого... - person SigSegOwl; 19.07.2017
comment
Хорошо, спасибо. Знаете ли вы, является ли ANGLE жизнеспособной альтернативой? - person Dan; 19.07.2017
comment
не уверен, вы можете попробовать это, конечно, но я бы попытался определить проблему немного больше. вы можете установить QSG_RENDER_TIMING=1 как переменную среды и посмотреть, какие тайминги вы получите при изменении размера. таким образом вы определенно можете определить, что рендеринг действительно является проблемой. также проверьте ссылку Scene Graph, которую я разместил выше, чтобы получить советы по производительности! - person SigSegOwl; 19.07.2017
comment
ANGLE, скорее всего, ничего не изменит, может быть даже хуже. Проблема не в производительности графики, и ANGLE ее не улучшит, так как это по сути эмуляция. - person dtech; 19.07.2017