Bas*_*Ben 4 qt qml qqmlapplicationengine
我有一个基于QML的应用程序,main.qml从文件系统加载文件,如下所示:
myEngine->load("main.qml");
Run Code Online (Sandbox Code Playgroud)
这工作正常,但我想"重新加载"引擎,以防main.qml被更新版本替换.
我到目前为止所尝试的是load()再次调用,假设引擎会像其他Qt类一样自动重置.
不幸的是,这种情况并非如此.如果我再次调用该方法,将出现另一个窗口,其中包含更新的qml文件的内容,而原始窗口保持打开状态并继续显示旧的qml文件.
为了解决这个问题,我尝试调用load(QUrl()),然后clearComponentCache()对新文件进行最终加载调用.这导致相同的效果.
任何想法如何在应用程序运行时"正确"重新加载QML引擎?
我会尝试将其存储myEngine为堆上的指针,并在调用quit()后将其删除。然后您可以重建它以获得新版本的 QML 文件。
如果您出于某种原因不想这样做(例如,因为您想保留窗口或其他原因),您可以尝试使用 aLoader并以这种方式加载 QML 文件。然后你main.qml会看起来像这样:
import QtQuick 2.0
Loader {
source: "changing.qml"
}
Run Code Online (Sandbox Code Playgroud)
每当您检测到changing.qml发生更改时,只需切换 的active属性Loader即可触发文件的重新加载。
小智 5
刚看到这个,但是如果你还在试图解决这个问题 - 这是一个三步过程,你有一些.
你必须关闭QQmlApplicationEngine第一个创建的窗口.在我的情况下,我将第一个根对象拉出QQmlApplicationEngine并将其转换为QQuickWindow,然后调用close().
现在你可以打电话clearComponentCache了QQmlApplicationEngine.
这是我的窗口关闭代码所做的(注意我给了我的主窗口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();
Run Code Online (Sandbox Code Playgroud)
第三步当然是加载你的QML.
后来,我开始创建一个QQuickView窗口而不是QQmlApplicationEngine,所以我可以调用clearComponentCache然后setSource(我不喜欢用户看到UI窗口消失然后重新出现.)