QML 加载程序不显示 .qml 文件上的更改



我有main.qmldynamic.qml文件,我想使用 Loader {}main.qml上加载dynamic.qml
dynamic.qml文件的内容是动态的,另一个程序可能会更改其内容并覆盖它。所以我写了一些C++代码来检测文件和触发信号的更改。
我的问题是我不知道如何强制加载器重新加载文件。

这是我目前的工作:

MainController {
    id: mainController
    onInstallationHelpChanged: {
        helpLoader.source = "";
        helpLoader.source = "../dynamic.qml";
    }
}
Loader {
    id: helpLoader
    anchors.fill: parent
    anchors.margins: 60
    source: "../dynamic.qml"
}



我认为QML引擎缓存dynamic.qml文件。因此,每当我想重新加载加载器时,它都会显示旧内容。有什么建议吗?

在将

Loaders source 属性设置为空字符串后,需要在 QQmlEngine 上调用 trimComponentCache()。换句话说:

helpLoader.source = "";
// call trimComponentCache() here!!!
helpLoader.source = "../dynamic.qml";

为了做到这一点,你需要向QML公开一些C++对象,QML引用了你的QQmlEngine(Qt和StackOverflow上的许多例子可以帮助解决这个问题)。

trimComponentCache告诉QML忘记所有当前未使用的组件,只做你想要的。

更新 - 更详细地解释:

例如,在某处定义了一个类,该类接受指向 QQmlEngine 的指针并公开 trimComponentCache 方法:

class ComponentCacheManager : public QObject {
    Q_OBJECT
public:
    ComponentCacheManager(QQmlEngine *engine) : engine(engine) { }
    Q_INVOKABLE void trim() { engine->trimComponentCache(); }
private:
    QQmlEngine *engine;
};

然后,在创建 QQuickView 时,将上述项之一绑定为上下文属性:

QQuickView *view = new QQuickView(...);
...
view->rootContext()->setContextProperty(QStringLiteral("componentCache", new ComponentCacheManager(view->engine());

然后在您的 QML 中,您可以执行以下操作:

helpLoader.source = "";
componentCache.trim();
helpLoader.source = "../dynamic.qml";

我希望有一个纯粹的QML解决方案。我注意到loader.source是一个 url ( file:/// ),并记得如何使用 HTML,您可以避免在请求中使用 ?t=Date.now() 进行 HTTP 缓存。尝试在loader.source末尾添加?t=1234,果然,它有效。

import QtQuick 2.0
Item {
    Loader {
        id: loader
        anchors.fill: parent
        property string filename: "User.qml"
        source: filename
        function reload() {
            source = filename + "?t=" + Date.now()
        }
    }
    Timer {
        id: reloadTimer
        interval: 2000
        repeat: true
        running: true
        onTriggered: {
            loader.reload();
        }
    }
}

我还编写了另一个示例,该示例将使用XMLHttpRequest触发重新加载之前检查文件内容的更改。

import QtQuick 2.0
Item {
    Loader {
        id: loader
        anchors.fill: parent
        property string filename: "AppletUser.qml"
        property string fileContents: ""
        source: ""
        function reload() {
            source = filename + "?t=" + Date.now()
        }
        function checkForChange() {
            var req = new XMLHttpRequest();
            req.onreadystatechange = function() {
                if (req.readyState === 4) {
                    if (loader.fileContents != req.responseText) {
                        loader.fileContents = req.responseText;
                        loader.reload();
                    }
                }
            }
            req.open("GET", loader.filename, true);
            req.send();
        }
        onLoaded: {
            console.log(source)
        }
        Timer {
            id: reloadTimer
            interval: 2000
            repeat: true
            running: true
            onTriggered: loader.checkForChange()
        }
        Component.onCompleted: {
            loader.checkForChange()
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新