[Interest] Problems with qt_add_qml_module

Ulf Hermann ulf.hermann at qt.io
Wed Oct 25 09:23:27 CEST 2023


> The first argument to the `qt_add_qml_module()` function is *not* a new 
> target to be defined by the call.

You can also give it an existing target. See all our examples that first 
create an executable target and then attach a QML module to it.

> Furthermore, the `SOURCES` argument isn't a list of files that 
> are to be compiled into a new artefact (library or executable). 

They are also compiled into your target. You don't have to list them 
twice. All sources already present on the target will also be inspected 
by moc and subsequently qmltyperegistrar.

> It is also worth 
> noting that for the introspection only headers are needed, i.e. the 
> `SOURCES` argument to `at_add_qml_module()` only needs to list headers 
> that define QML types (those that use the `QML_ELEMENT`, typically).
> Is this description accurate so far ?

No! Do add the sources. Otherwise you'll get unresolved symbols 
somewhere down the line.

> There are a few caveats I observed: The call to `qt_add_qml_module()` 
> has to occur in the same CMakeLists.txt file as the associated backing 
> target definition (e.g. `add_library()`), or else make complains about 
> missing symbols.

While it is probably a good idea to keep the target and the QML module 
together, your missing symbols are probably due to missing source files.

> Further, the `OUTPUT_DIRECTORY` argument to 
> `qt_add_qml_module()` seems to be required (at least if more than one 
> QML modules are defined).

No! Do not add a custom output directory unless you know exactly what 
you are doing. The default output directory is fine in 99% of the cases 
and will make it much easier to find the module at run time.

> It is probably assumed that the structure of the QML modules matches the 
> structure of the underlying C++ libraries. 

No! The structure of the QML modules matches their URIs. You put a 
module my.fine.module into a directory at a path my/fine/module from the 
directory of your executable. That, at least, is the easiest and 
recommended way to do it. You can structure your C++ libraries whatever 
way you like. If you need to expose a type from some other library in 
your QML module there is QML_FOREIGN for that.

> One thing that bothers me in particular is 
> that The classes that I want to reflect into QML are supposed to contain 
> the `QML_ELEMENT` macro, which I think is a bit intrusive. 

You can use QML_FOREIGN to expose classes that don't have any QML macros 
themselves.

> All that being said, am I on the right track, or am I still 
> fundamentally misunderstanding how to use QML with Qt6 ?

Well ... maybe you want to read 
https://doc.qt.io/qt-6/qtqml-writing-a-module.html

best,
Ulf


More information about the Interest mailing list