[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