在我的 QML 应用程序中,我想实现热重载。为此,我们要做的主要事情是从文件系统加载所有资源,而不是 Qt 资源系统。
一个人必须做两件事:
prefer ./path/to/module
添加到每个 QML 模块的 qmldir
文件这允许更改源文件,重新启动应用程序而不重建它,并且更改会反映在正在运行的应用程序中。
现在我发现了一个特殊情况,这不起作用。 QML 模块可以包含 javascript 资源并公开其功能。在这些 javascript 文件中,可以导入其他 QML 模块。
在重现此问题的最小应用程序中,我在
A
文件旁边定义了两个模块 B
和 Main.qml
。这两个模块都只包含一个 javascript 资源:
A.js
:
.pragma library
.import B as B
function test() {
console.log("Calling B from A")
B.B.test()
}
B.js
:
.pragma library
function test() {
console.log("Hello from B")
}
在模块
A
内部,我定义了一个简单的函数test
,它在控制台上打印一条消息,并调用模块test
的函数B
,它也只是打印到控制台。
我的
Main.qml
文件如下所示:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import A
import B
ApplicationWindow {
id: root
width: 1920
height: 1080
visible: true
Component.onCompleted: {
console.log("Calling A from Main")
A.test()
console.log("Calling B from Main")
B.test()
}
}
启动此应用程序时,控制台输出如下所示:
qml: Calling A from Main
qml: Calling B from A
qml: Hello from B
qml: Calling B from Main
qml: Hello from B
现在我修改里面打印的消息
B.test()
并重新启动应用程序而不重建它:
qml: Calling A from Main
qml: Calling B from A
qml: Hello from B
qml: Calling B from Main
qml: Hello from B MODIFIED
注意,只有当模块 B
从主 QML 模块(或任何其他 QML 文件,甚至从其他模块内加载,正如我在实际应用程序中测试的那样)中加载时,更改才会反映出来。但是,一旦模块被导入到javascript 资源中,导入似乎就不再尊重
prefer ./path/to/module
文件的
qmldir
行。 有人知道如何解决这个问题吗?我正在使用 CMake 构建我的 Qt 应用程序。
其他资源: