SectorenAutomotiveConsumer electronicsIndustrial automationMedicalPlatformenTechnologyOver onsBlogContact
Invisto nv
Voetbalstraat 17
8870 Izegem

Introduction to QML modules in Qt6

Bob Messiaen
Bob Messiaen
Introduction to QML modules in Qt6

1. QML Modules

What are QML modules?

A QML module is a collection of QML components/elements, JavaScript files, and assets that can be imported and used in other QML applications. The modules allow for encapsulation and reuse of code by using namespaces and versioning. Basically allowing you to have a clean and modularized project structure.

import QtQuick
import InvistoControls 1.3

Window {
  width: 640
  height: 480
  visible: true
  title: qsTr("Hello World")
  IvProgressBar {
  value: 50

In the code snippet above we import the InvistoControls module, version 1.3. IvProgressBar is one of the components included in the module.

With Qt6.2 a more user-friendly way of creating modules was introduced. The CMake API was finalised and gave us the qt_add_qml_module command. Let’s take a look at this new command.

2. CMake support

qt_add_qml_module is a CMake function provided by the Qt framework that is used to create and define a new QML module. It generates the necessary CMake rules to build and install the module and its components.

The qt_add_qml_module function takes several arguments, including the module name, the QML source files, and any additional dependencies. The function also allows the specification of a plugin type, which can be set to "qmltypes" or "qmlplugin", depending on the type of module being created.

Here is an example usage of qt_add_qml_module:

  URI be.invsito.controls
  PLUGIN_TYPE qmltypes

In this example, a new QML module named "InvistoControls" is defined with a URI of "be.invsito.controls" and a version of 1.0. The QML source files for the module are specified as "InvistoButton.qml" and "InvistoProgressBar.qml". The plugin type is set to "qmltypes", and the module has a dependency on the "QtQuick" module.

Once this function is called, the CMake build system will generate the necessary rules to build and install the QML module and its components. The module can then be imported and used in QML applications using the specified URI.

What are the major advantages we have with this new command?

  • We don’t have to write the qmldir and qmltypes files ourselves.
  • We don’t have to create a qrc resource file.
  • A module can easily be a mixture of QML and C++ components. C++ types annotated with QML_ELEMENT and friends are automatically registered.
  • Automatically runs qmlcachegen and qmllint.

3. Some examples

The examples below serve as an introduction to QML modules and the qt_add_qml_module command. While there is a lot more to talk about, this is simply an introduction to the most commonly used cases.

3.1 Building a QML application

The title speaks for itself I guess. You want to build a highly performant, fluidly animated and visually appealing application in qml.

By using qt_add_qml_module you can easily include your qml and resource files into the project. Easy, no tricks involved.

Let's take look at the example below:

The full source code can be found here.

First we have the main.qml file.

import QtQuick

Window {
  width: 640
  height: 480
  visible: true
  title: qsTr("Hello World")

  Logo {
  anchors.centerIn: parent

And then the main.cpp that loads our qml file.


int main(int argc, char *argv[])
  QGuiApplication app(argc, argv);
  QQmlApplicationEngine engine;
  const QUrl url(u"qrc:/invisto/main.qml"_qs);
  return app.exec();

And to finish, the CMakeLists.txt to build the project.

cmake_minimum_required(VERSION 3.16)

project(QMLModuleApplicationDemo VERSION 1.0 LANGUAGES CXX)


find_package(Qt6 6.2 COMPONENTS Quick Gui REQUIRED)


  URI invsito
target_link_libraries(myapp PRIVATE Qt6::Gui Qt6::Quick)

The app we are building here is displaying the Invisto logo in the centre of the screen. The logo itself is wrapped in a Logo.qml.

So what’s important here, looking at our CMake file and the qt_add_qml_module command:

  • URI: this will make sure our qml and resource files are placed into qrc:/${URI} in the resource file system.
  • VERSION: version of the module.
  • QML_FILES: Listing up the qml files you want to include in the module.
  • RESOURCES: Listing up the resource files you want to include in the module.

3.2 Building a QML module that registers a C++ class as a QML type

In this example we want to show how to write a C++ class and register it as a QML type.

The full source code can be found here.

The header file of our C++ class:

#pragma once


class CustomElement : public QObject
  Q_PROPERTY(int counter READ counter WRITE setCounter
NOTIFY counterChanged)

    int counter() const;
    void setCounter(int value);
  void counterChanged();
  int m_counter;

And the CMakeLists.txt

  URI qmllibs.demolib
    custom_element.h custom_element.cpp

As you can see it’s very straightforward to do the registration:

  • In the header file you need to add QML_ELEMENT. QML_ELEMENT is a C++ macro provided by the Qt framework that is used to register a new custom QML element.
  • In the CMakeLists.txt file you add your source files to the SOURCES parameter.

4. Conclusion

These are just two small examples of what is possible with qt_add_qml_module. Legacy projects that are going through an overhaul from Qt5 from to Qt6 can definitely benefit from using the new API. The new CMake support is a lot easier to work with, you have to write less files. Qmllint is run automatically, forcing you to keep your QML code clean.

Qt6.2 (and above) projects should be using this from the start.

More documentation is available at the website of the Qt Group. Make sure to take a look at:

Ook interesse in een state-of-the-art interface die uw product naar een hoger niveau tilt?

Let's talk!

Enkele van onze klanten

Logo HoneywellLogo Picanol GroupLogo CiscoLogo BekaertLogo Universiteit GentLogo Renson