5

我有一个基于 QML 的应用程序,它main.qml从文件系统加载文件,如下所示:

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

这工作正常,但我想“重新加载”引擎,以防 main.qml 被更新版本替换。

到目前为止,我尝试load()再次调用,假设引擎会像在其他 Qt 类中一样自动重置自己。

不幸的是,这种情况并非如此。如果我再次调用该方法,将出现另一个窗口,其中包含更新的 qml 文件的内容,而原始窗口保持打开状态并继续显示旧的 qml 文件。

为了解决这个问题,我尝试调用load(QUrl()),然后clearComponentCache()对新文件进行最终加载调用。这导致相同的效果。

任何想法如何在应用程序运行时“正确”重新加载 QML 引擎?

4

2 回答 2

5

刚刚看到这个,但如果你仍然想弄清楚 - 这是一个三步过程,你已经掌握了一些。

  1. 您必须关闭QQmlApplicationEngine第一个创建的窗口。在我的情况下,我将第一个根对象从 中拉出QQmlApplicationEngine并将其转换为QQuickWindow,然后调用close().

  2. 现在您可以调用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();

第三步当然是加载你的 QML。

后来,我开始创建一个QQuickView窗口而不是QQmlApplicationEngine,这样我就可以调用clearComponentCachethen setSource(我不喜欢用户看到 UI 窗口消失然后重新出现。)

于 2016-03-15T00:43:50.770 回答
4

我会尝试myEngine在堆上存储为指针,并在调用quit()后将其删除。然后你可以重建它以获得新版本的 QML 文件。

如果您出于某种原因不想这样做(例如,因为您想保留窗口或其他原因),您可以尝试使用 aLoader并以这种方式加载 QML 文件。然后你main.qml会看起来像这样:

import QtQuick 2.0

Loader {
     source: "changing.qml"
}

每当您检测到changing.qml已更改时,只需切换 的active属性Loader即可触发文件的重新加载。

于 2015-05-12T16:35:33.273 回答