问题
I have a QML-based app that loads a main.qml
file from the file system like this:
myEngine->load("main.qml");
This works fine, but I'd like to "reload" the engine in case the main.qml was replaced with a newer version.
What I tried so far was calling load()
again, assuming that the engine will automatically reset itself like in other Qt classes.
Unfortunately this is not the case. If I call the method again, another window will appear with the contents of the updated qml file, while the original window stays open and continues to display the old qml file.
To fix this I tried to call load(QUrl())
, followed by clearComponentCache()
and a final load call for the new file. This results in the same effect.
Any ideas how I can "properly" reload a QML engine while the application is running?
回答1:
I would try storing myEngine
as a pointer on the heap, and deleting it after calling quit(). Then you can reconstruct it to get the new version of the QML file.
If you don't want to do this for some reason (e.g. because you want to keep the window around or whatever), you might try using a Loader
and loading the QML file that way. Your main.qml
would then look something like this:
import QtQuick 2.0
Loader {
source: "changing.qml"
}
Whenever you detect that changing.qml
has changed, just toggle the active property of Loader
to trigger a reload of the file.
回答2:
Just saw this, but if you're still trying to figure this out - it's a three step process, and you have some of it.
You MUST close window created by the
QQmlApplicationEngine
first. In my case I pulled the first root object off theQQmlApplicationEngine
and cast it toQQuickWindow
, then callclose()
.Now you can call
clearComponentCache
on theQQmlApplicationEngine
.
This is what my window closing code does (note that I gave my main window an 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 is, of course, to load your QML.
Later, I moved to creating a QQuickView
window instead of QQmlApplicationEngine
, so that I could just call clearComponentCache
and then setSource
(I didn't like the user seeing the UI window vanish and then re-appear.)
来源:https://stackoverflow.com/questions/30196113/properly-reloading-a-qqmlapplicationengine