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