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?
source to share
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.
source to share
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 fromQQmlApplicationEngine
and applied it toQQuickWindow
and then callclose()
. -
You can now call
clearComponentCache
onQQmlApplicationEngine
.
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.)
source to share