In my QML application, I want to implement hot reloading. The main thing one has to do for that is to load all resources from the file system, not the Qt resource system.
One has to do two things:
prefer ./path/to/module
to each QML module's qmldir
fileThis allows to change a source file, restart the application without rebuilding it, and the changes are reflected in the running application.
Now I have found a special case, where this does not work. QML modules can contain javascript resources and expose their functions. Inside these javascript files, one can import other QML modules.
In my minimal application that reproduces this problem, I have defined two modules A
and B
next to my Main.qml
file. Both of these modules simply contain one javascript resource:
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")
}
Inside module A
, I define a simple function test
, that prints a message on the console and also calls the function test
of module B
, which also just prints to the console.
My Main.qml
file looks like this:
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()
}
}
When starting this application, the console output looks like this:
qml: Calling A from Main
qml: Calling B from A
qml: Hello from B
qml: Calling B from Main
qml: Hello from B
Now I modify the message being printed inside B.test()
and restart the application without rebuilding it:
qml: Calling A from Main
qml: Calling B from A
qml: Hello from B
qml: Calling B from Main
qml: Hello from B MODIFIED
Notice, how the changes are only reflected, when module B
is loaded from within the main QML module (or any other QML file, even from within other modules, as I have tested in my real application). But as soon as the module gets imported inside a javascript resource, the import seems to no longer respect the prefer ./path/to/module
line of the qmldir
file.
Does somebody know how one could work around this? I am using CMake to build my Qt application.
Additional resources:
I created a bugreport on the QT website.
Some kind people there attended my problem and confirmed, that at least the difference in the behaviour of importing from a .js
file vs. a .qml
file is not intended.