QML Loader不显示.qml文件的更改

S.M*_*avi 10 caching dynamic-data qml qt5

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

这是我目前的工作:

MainController {
    id: mainController
    onInstallationHelpChanged: {
        helpLoader.source = "";
        helpLoader.source = "../dynamic.qml";
    }
}

Loader {
    id: helpLoader

    anchors.fill: parent
    anchors.margins: 60
    source: "../dynamic.qml"
}
Run Code Online (Sandbox Code Playgroud)



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

ksi*_*ons 9

将Loaders 属性设置为空字符串后,需要调用trimComponentCache()QQmlEngine .换一种说法:source

helpLoader.source = "";
// call trimComponentCache() here!!!
helpLoader.source = "../dynamic.qml";
Run Code Online (Sandbox Code Playgroud)

为了做到这一点,你需要向CML公开一些C++对象,它引用了你的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;
};
Run Code Online (Sandbox Code Playgroud)

然后,当您创建QQuickView时,将上述其中一个绑定为上下文属性:

QQuickView *view = new QQuickView(...);
...
view->rootContext()->setContextProperty(QStringLiteral("componentCache", new ComponentCacheManager(view->engine());
Run Code Online (Sandbox Code Playgroud)

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

helpLoader.source = "";
componentCache.trim();
helpLoader.source = "../dynamic.qml";
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你。我通过使用 `qmlRegisterSingletonType` 创建 Qml 类型来实现你的建议。但是`trimComponentCache()` 不起作用。相反,`clearComponentCache()` 有效。谢谢你,兄弟! (2认同)