Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QML Loader not shows changes on .qml file

I have main.qml and dynamic.qml files that i want to load dynamic.qml on main.qml using Loader {}.
Content of dynamic.qml file is dynamic and another program may change its content and overwrite it. So i wrote some C++ code for detecting changes on file and fires Signal.
My problem is that I don't know how can i force Loader to reload file.

This is my current work:

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

Loader {
    id: helpLoader

    anchors.fill: parent
    anchors.margins: 60
    source: "../dynamic.qml"
}



I think that QML Engine caches dynamic.qml file. So whenever I want to reload Loader, it shows old content. Any suggestion?

like image 684
S.M.Mousavi Avatar asked Oct 26 '13 08:10

S.M.Mousavi


1 Answers

You need to call trimComponentCache() on QQmlEngine after you have set the Loaders source property to an empty string. In other words:

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

In order to do that, you'll need to expose some C++ object to QML which has a reference to your QQmlEngine (lots of examples in Qt and on StackOverflow to help with that).

trimComponentCache tells QML to forget about all the components it's not current using and does just what you want.

Update - explaining in a bit more detail:

For example, somewhere you define a class that takes a pointer to your QQmlEngine and exposes the trimComponentCache method:

class ComponentCacheManager : public QObject {
    Q_OBJECT
public:
    ComponentCacheManager(QQmlEngine *engine) : engine(engine) { }

    Q_INVOKABLE void trim() { engine->trimComponentCache(); }

private:
    QQmlEngine *engine;
};

Then when you create your QQuickView, bind one of the above as a context property:

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

Then in your QML you can do something like:

helpLoader.source = "";
componentCache.trim();
helpLoader.source = "../dynamic.qml";
like image 189
ksimons Avatar answered Oct 08 '22 17:10

ksimons