【问题标题】:Properly reloading a QQmlApplicationEngine正确重新加载 QQmlApplicationEngine
【发布时间】:2015-07-23 15:16:24
【问题描述】:

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

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

这很好用,但我想“重新加载”引擎,以防 main.qml 被更新的版本替换。

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

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

为了解决这个问题,我尝试调用load(QUrl()),然后调用clearComponentCache(),最后调用新文件。这会产生相同的效果。

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

【问题讨论】:

  • clearComponentCache() 看起来只与组件有关,因此不考虑这些组件的实例。

标签: qt qml qqmlapplicationengine


【解决方案1】:

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

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

  2. 现在您可以在QQmlApplicationEngine 上致电clearComponentCache

这就是我的窗口关闭代码所做的(注意我给了我的主窗口一个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,这样我就可以调用clearComponentCache 然后setSource(我不喜欢用户看到 UI 窗口消失然后重新- 出现。)

【讨论】:

  • 您好,谢谢您的回复!这是一个很好的方法,我会试一试。同时,我找到了另一种方法来执行此操作:由于我们使用文件名 URL 从文件系统加载 QML 文件,因此在 URL 末尾添加随机“?nocache = 1238123”也解决了缓存/重新加载问题.当然,对于引擎来说,这不像您的方法那样“重新启动”,但到目前为止有效。
  • 感谢 nocache 提示 :)
【解决方案2】:

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

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

import QtQuick 2.0

Loader {
     source: "changing.qml"
}

当您检测到changing.qml 发生变化时,只需切换Loaderactive 属性即可触发文件的重新加载。

【讨论】:

  • 呃。我想我应该收拾行李回家了。太明显了,疼。谢谢!在这里,有一些代表点。 :)
  • 我无法通过使用指针和退出以任何方式做到这一点,我会调用退出并连接到退出信号,尝试删除它总是会导致崩溃,尝试断开连接() , deleteLater() 但无济于事,加载器解决方案完美运行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
  • 1970-01-01
相关资源
最近更新 更多