Correctly reloading the QQmlApplicationEngine

I have a QML based application that downloads a file main.qml

from the file system like this:

myEngine->load("main.qml");

      

This works great, but I would like to "reload" the engine if main.qml was replaced with a newer version.

What I've tried so far was calling load()

again, assuming the engine will automatically reset itself, as in other Qt classes.

Unfortunately, this is not the case. If I call the method again, another window appears with the contents of the updated qml file, while the original window remains open and continues to display the old qml file.

To fix this, I tried to call load(QUrl())

then the clearComponentCache()

final download call for the new file. This leads to the same effect.

Any ideas how I can "properly" reload the QML engine while the application is running?

+3


source to share


2 answers


I would try to store myEngine

as a heap pointer and delete it after the quit () call . Then you can restore it to get a new version of the QML file.

If you don't want to do this for any reason (like because you want to keep the window around or whatever), you can try using Loader

and loading the QML file that way. Yours main.qml

will look something like this:



import QtQuick 2.0

Loader {
     source: "changing.qml"
}

      

Whenever you find what changing.qml

has changed, just toggle the active property Loader

to trigger a file reload.

+3


source


Just saw it, but if you are still trying to figure it out - this is a three step process and you have it.

  • You must first close the window created with QQmlApplicationEngine

    . In my case, I pulled the first root object from QQmlApplicationEngine

    and applied it to QQuickWindow

    and then call close()

    .

  • You can now call clearComponentCache

    on QQmlApplicationEngine

    .

This is what my window close code is doing (note that I gave my main window objectName

)



QObject* pRootObject = in_pQmlApplicationEngine->rootObjects().first();
Q_ASSERT( pRootObject != NULL );
Q_ASSERT( pRootObject->objectName() == "mainWindow" );

QQuickWindow* pMainWindow = qobject_cast<QQuickWindow*>(pRootObject);
Q_ASSERT( pMainWindow );
pMainWindow->close();

      

The third step, of course, is to load your QML.

Later I moved on to create a window QQuickView

instead QQmlApplicationEngine

, so that I could just call clearComponentCache

and then setSource

(I didn't like the fact that the user would see the UI window disappear and then re-appear.)

+4


source







All Articles