너를 속였다
너를 속였다

Reputation: 1069

How to use QML_ELEMENT with cmake

The doc shows I can use QML_ELEMENT macro to create QML types from C++ by adding some variables in qmake's .pro file. But I'm using cmake

Upvotes: 17

Views: 9691

Answers (2)

Adrien Leravat
Adrien Leravat

Reputation: 2789

Edit (Qt 6.x)

This answer was originally posted for Qt 5.15. Now that Qt 6 is available, and if you are using Qt 6, refer to the answer from @Adversus.

Original answer (Qt 5.x)

From what I can see, CONFIG += qmltypes, which is required to use QML_ELEMENT, is not yet supported in CMake by looking at the documentation, even for the master branch.

And the efforts to provide a python .pro to cmake converter are for Qt6, not merged, and not functional as far as I can tell, by testing them from util on the wip/cmake branch (the CMakeLists.txt didn't have relevant information). You can see that the actual conversion script does test for qmltypes presence in CONFIG, but it doesn't seem to map to anything usable for CMake.

Solution

Instead of using QML_ELEMENT and CONFIG += qmltypes, which is brand new from Qt 5.15 (latest when writing this), and not supported at this time with CMake, use the good old qmlRegisterType from C++:

#include "YouCustomCppClass.h"

int main(int argc, char** argv) {

    // Let you import it with "import ModuleName 1.0" on the QML side
    qmlRegisterType<YouCustomCppClass>("ModuleName", 1, 0, "YourQmlComponent");

    //Create your QML view or engine
}

This won't require anything specific on the project file side, as long as your code/plugin executes qmlRegisterType statement.

You can refer to Qt's documentation, same page as yours, but for Qt 5.14 instead of latest, which describes exactly that: Writting QML extensions for C++ | Qt 5.14

Upvotes: 11

Adversus
Adversus

Reputation: 2226

Update (Qt 6.2+)

As of Qt 6.2, qt_add_qml_module is a single command for building qml modules that should take care of virtually everything, replacing amongst others the old qt6_qml_type_registration command.

Old answer (Qt 6.0/6.1)

Now that Qt 6.0 is out this is supported, albeit poorly documented. What you need now is:

set_target_properties(foo PROPERTIES
    QT_QML_MODULE_VERSION 1.0
    QT_QML_MODULE_URI     Foo
)

qt6_qml_type_registration(foo)

you can then do in qml:

import Foo

and you'll have access to types that have QML_ELEMENT and friends. Notes:

  • Two files are created in the build output folder, <project>_qmltyperegistrations.cpp and <project>.qmltypes, if your imports are failing you can look at those to see which types are missing. I found that I needed to do full recompiles sometimes after adding/removing registered types.
  • Qt examples have been migrated to cmake, so take a look at e.g. Examples/Qt-6.0.0/quick/tableview/gameoflife to see it in action
  • There are now pro2cmake.py and run_pro2cmake.py files in the Qt sources at Qt/6.0.0/Src/qtbase/util/cmake. They are mentioned on this Readme page, you can find them here, haven't tried it myself.

Upvotes: 12

Related Questions