使用 ApplicationWindow 时热重载 QML
Hot reload QML when using ApplicationWindow
有没有人能够在使用 ApplicationWindow
时热重载所有 QML 文件?我找到了一些像 https://qml.guide/live-reloading-hot-reloading-qml/ and https://www.slideshare.net/ICSinc/how-best-to-realize-a-runtime-reload-of-qml 这样的例子,但他们大多使用 Loader
并且由于 ApplicationWindow
需要成为根项,所以这不起作用(没有 window 出现)重新加载所有 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")));
}
这种代码可以工作一次,window 会消失并重新出现,但快捷方式只能工作一次,但不会第二次...
有什么实现方法吗?
这是我所做的并且工作正常:
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()
}
}
}
有没有人能够在使用 ApplicationWindow
时热重载所有 QML 文件?我找到了一些像 https://qml.guide/live-reloading-hot-reloading-qml/ and https://www.slideshare.net/ICSinc/how-best-to-realize-a-runtime-reload-of-qml 这样的例子,但他们大多使用 Loader
并且由于 ApplicationWindow
需要成为根项,所以这不起作用(没有 window 出现)重新加载所有 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")));
}
这种代码可以工作一次,window 会消失并重新出现,但快捷方式只能工作一次,但不会第二次...
有什么实现方法吗?
这是我所做的并且工作正常: 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()
}
}
}