正确地重新加载QQmlApplicationEngine

时间:2015-05-12 16:05:02

标签: qt qml qqmlapplicationengine

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

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

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

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

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

要解决此问题,我尝试调用load(QUrl()),然后调用clearComponentCache()并调用新文件的最终加载调用。这会产生同样的效果。

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

2 个答案:

答案 0 :(得分:5)

刚看到这个,但是如果你还在试图解决这个问题 - 这是一个三步骤的过程,而且你有一些过程。

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

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

  3. 这就是我的窗口关闭代码所做的(注意我给了我的主窗口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窗口消失然后重新出现。)

答案 1 :(得分:4)

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

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

import QtQuick 2.0

Loader {
     source: "changing.qml"
}

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