【问题标题】:Hot reload QML when using ApplicationWindow使用 ApplicationWindow 时热重载 QML
【发布时间】:2019-08-04 10:39:18
【问题描述】:

是否有人能够在使用ApplicationWindow 时热重载所有 QML 文件?我发现了一些例子,如https://qml.guide/live-reloading-hot-reloading-qml/https://www.slideshare.net/ICSinc/how-best-to-realize-a-runtime-reload-of-qml,但大多数情况下他们使用Loader,因为ApplicationWindow 需要作为根项,这不起作用(没有出现窗口)只是重新加载所有 QML 内容。

我试过了:

ApplicationWindow {
    id: window
    visibility: "FullScreen"

    Shortcut {
        sequence: "F5"
        context: Qt.ApplicationShortcut
        onActivated: {
            window.close();
            app.loadQml();
        }
    }
    ...
}

app 是我在 C++ 端设置的上下文属性,而函数确实如此:

void App::loadQml()
{
    qml_engine_.clearComponentCache();
    // Use "qrc:/Main.qml" for Qt Resource System.
    // Use "Main.qml" for file system.
    qml_engine_.load(QUrl(QStringLiteral("Main.qml")));
}

这种代码工作一次,窗口消失并重新出现,但快捷方式只工作一次,但没有第二次......

有什么想法可以实现吗?

【问题讨论】:

  • 你能分享一个完整的最小例子吗?找出问题会更容易。我很惊讶它第一次工作,你正在关闭 Shortcut 的父级

标签: qt qml reload hot-reload applicationwindow


【解决方案1】:

这是我所做的,并且运行良好: main.cpp:

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "app.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QApplication app(argc, argv);

    QQmlApplicationEngine engine;

    App appp;
    appp.setEngine(&engine);

    engine.rootContext()->setContextProperty("app", &appp);

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

app.cpp:

#include "app.h"

App::App(QObject *parent): QObject (parent)
{

}

App::~App(){}

void App::loadQml()
{
    m_engine->load(QUrl(QStringLiteral("qrc:/main.qml")));
}

app.h:

#ifndef APP_H
#define APP_H
#include <QObject>
#include <QQmlApplicationEngine>

class App: public QObject
{

    Q_OBJECT
public:
    App(QObject* parent = Q_NULLPTR);
    ~App();

    Q_INVOKABLE void loadQml();
    void setEngine(QQmlApplicationEngine *engine) { m_engine = engine; }

private:
    QQmlApplicationEngine* m_engine;
};

#endif // APP_H

main.qml:

import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.11
import QtQuick.Window 2.11

Window {
    id: window
    width: 1000
    height: 1000
    visible: true

    Shortcut {
        sequence: "F5"
        onActivated: {
            window.close()
            app.loadQml()
        }
    }
}

【讨论】:

  • 您也可以将Window 替换为ApplicationWindow,在每次启动时仍然有效
  • 删除context: Qt.ApplicationShortcut
  • 感谢您回答@bardao。删除 context: Qt.ApplicationShortcut 确实改善了它。我的应用程序现在在退出时崩溃,但至少热重载似乎有效。详细信息:在可能的情况下,appQGuiApplication 的子类,因此您的代码中没有apppapp。感谢您的帮助!
  • @marsl 在一个最小的例子中重现这个问题会非常有帮助:)
猜你喜欢
  • 2019-02-14
  • 1970-01-01
  • 2021-03-10
  • 2017-05-28
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 2019-12-03
相关资源
最近更新 更多