避免QQuickView延迟加载QML

4
这是我的情况。我试图将qml与大多数基于窗口小部件的UI结合起来。为此,我正在使用QQuickView和QWidget :: createWindowContainer。我不能使用QQuickWidget,因为我需要将窗口转换为本机窗口,而QQuickWidget不喜欢这样做。但回到问题。
我的问题是第一次显示视图时,它需要约半秒钟的时间来加载,从而引起非常明显的闪烁。之后,我可以随意隐藏/显示该视图,它会立即显示。只有第一次加载qml。我相当确定是加载qml导致问题。因为我有两个不同的QQuickViews,它们都以相同的qml作为源。但是在其中任何一个加载一次后,另一个就没有显示立即的问题。
我尝试尽早调用view上的show()以使其及时加载。但这会导致qml在任何小部件显示之前出现一瞬间。
是否有人遇到类似的问题?如何使QQuickView行为良好。
编辑:我使用的是Qt 5.4.2,由于各种原因,我无法更新到更新版本。
1个回答

3

我本来想说你可以使用与这个答案中相同的方法,但似乎即使这样加载QML也为时过早。尽管这很麻烦,但我能想到的唯一另一种方法是使用一个非常短的Timer

main.cpp:

#include <QtWidgets>
#include <QtQuick>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0) :
        QMainWindow(parent)
    {
        QQuickView *view = new QQuickView();
        QWidget *container = QWidget::createWindowContainer(view, this);
        container->setFocusPolicy(Qt::TabFocus);
        view->rootContext()->setContextProperty("window", view);
        view->setSource(QUrl("qrc:/main.qml"));
        setCentralWidget(container);
        resize(400, 400);
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

#include "main.moc"

main.qml:

import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 2.0

Item {
    anchors.fill: parent

//    Connections {
//        target: window
//        onAfterSynchronizing: loader.active = true
//    }

    Timer {
        running: true
        repeat: true
        interval: 50
        onTriggered: {
            loader.active = true
        }
    }

    Loader {
        id: loader
        active: false
        sourceComponent: Column {
            anchors.fill: parent

            Repeater {
                model: 30000
                delegate: Button {
                    text: index
                }
            }
        }
    }

    BusyIndicator {
        running: loader.status === Loader.Null
        anchors.centerIn: parent
    }
}

为了简洁起见,我将“繁重”的QML放入sourceComponent中,但您也可以使用source属性指向URL。 BusyIndicator在渲染线程上运行其动画,因此它可以在GUI线程被阻塞时继续旋转。

我查看了你的解决方案,但是注意到你使用了我无法访问的qml组件。我很抱歉,我应该在问题中提到这一点。但希望这对其他遇到类似问题的人有用。 - Adam Rudas
你可以将 import QtQuick.Controls 2.0 更改为 import QtQuick.Controls 1.3(或者与 Qt 5.4.2 发布的 Controls 版本相对应的版本),这样它应该能够正常工作。 - Mitch
抱歉,我的错。我一定查错了。 我已经尝试了你的解决方案,但遗憾的是它无法解决我的问题。 如果你有一个需要加载时间的复杂qml,这很有用。我的问题是,即使是一个非常简单的一个按钮qml,在第一次加载时也需要花费几分之一秒的时间。使用你的解决方案,加载器本身需要花费几分之一秒的时间才能出现,我只能勉强看到加载圆圈,然后我的qml就出现了。 - Adam Rudas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接