[Interest] Porting custom QML plugin to the Qt6

Jakub Narolewski izowiuz at gmail.com
Wed Apr 28 21:54:16 CEST 2021


Lately, mostly for fame and glory, I decided to port some of my stuff from Qt5 to Qt6. 
Most of it went ok'ish - after some CMakeLists.txt hacking and 'modernizing' the code I 
was able to compile two of my dynamic libraries under Qt6.

Problems started with my custom QML plugin. Here after compiling and importing my module 
in my example app I got:
"qrc:/src/QML/MainWindow.qml:5:1: module "IzLibrary" plugin "IzLibraryPlugin" not found"

Well oopsie doopsie, some more work is needed. After quick look at:
https://doc.qt.io/qt-6/qtqml-modules-cppplugins.html

I spotted, I believe, the most important changes. QQmlExtensionPlugin being changed to 
QmlEngineExtensionPlugin, QML_ELEMENT added in Qt 5.15.X and removal of 
QQmlExtensionPlugin::registerTypes.

Then I noticed stuff about QML_IMPORT_NAME, QML_IMPORT_MAJOR_VERSION and 'CONFIG += 
qmltypes' that are supposed to be added to the .pro project files. And, although, docs are 
silent about CMake, there is handy example located at:
https://code.qt.io/cgit/qt/qtdeclarative.git/tree/examples/qml/qmlextensionplugins/CMakeLists.txt?h=6.0

I added to my CMakeLists.txt:

set_target_properties(
     IzLibraryPlugin
PROPERTIES
     QT_QML_MODULE_VERSION 1.0
     QT_QML_MODULE_URI IzLibrary
)

omitting, for the moment, the "QT_QMLTYPES_FILENAME imports/TimeExample/plugins.qmltypes" 
as I was typically generating .qmltypes manually using the supplied qmlplugindump and some 
associated CMake hackery.

I also added the:

qt6_qml_type_registration(IzLibraryPlugin)

And this is when first build error occurred. qt6_qml_type_registration seems to be trying 
to automate some of the QML type registration machinery and generates the 
"izlibraryplugin_qmltyperegistrations.cpp" file. In my case it looks like this:

#include <QtQml/qqml.h>
#include <QtQml/qqmlmoduleregistration.h>

#include <CountdownTimer.h>
#include <DoubleValidator.h>
#include <IntValidator.h>

void qml_register_types_IzLibrary()
{
     qmlRegisterTypesAndRevisions<IzLibrary::CountdownTimer>("IzLibrary", 1);
     qmlRegisterTypesAndRevisions<IzLibrary::DoubleValidator>("IzLibrary", 1);
     qmlRegisterTypesAndRevisions<IzLibrary::IntValidator>("IzLibrary", 1);
     QMetaType::fromType<QDoubleValidator *>().id();
     QMetaType::fromType<QIntValidator *>().id();
     qmlRegisterModule("IzLibrary", 1, 0);
}

static const QQmlModuleRegistration registration("IzLibrary", qml_register_types_IzLibrary);


But! My includes are not available under <SomeBeautifulHeader.h> but rather under 
"IzLibrary/SomeBeautifulHeader.h" as denoted by my target_include_directories:

# include directories for target
target_include_directories(
     IzLibraryPlugin
PUBLIC
     $<INSTALL_INTERFACE:include>
     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PRIVATE
     ${CMAKE_CURRENT_SOURCE_DIR}/private
)

So, my questions (for now :P) are:
Is this the intended behavior or have I fubared something and not added "something, 
somewhere" in my CMakeLists.txt?
Is there a documentation for the qt6_* cmake functions?
Is the stuff "qt6_add_qml_module" important or can I skip it?


More information about the Interest mailing list