Qt 5.15 provides a much improved way to represent C++ types for QML. Now you can specify the name and version of your module in a central place, and you no longer need to specify minor versions or revisions. In addition, the specifics of QML type registration can now be declared in a C++ class declaration.
So far, a common way to make C++ types available in QML has been to use the registration functions provided in the qqml.h header: qmlRegisterType(), qmlRegisterSingletonType(), qmlRegisterUncreatableType(), etc. This approach has its drawbacks:
you should always keep your type registrations in sync with the actual types. This is especially tedious if you're using revisions to make properties available across different import versions. Even if it isn't, the fact that you have to specify registration separately from the type is cumbersome, as you can easily lose track of how you registered which types into which modules.
Also, since you are registering your types procedurally, any QML tool cannot automatically determine which types are available in which imports. Qt Creator does have some heuristics that try to detect common logging patterns in C++ code, but this is incomplete. Finding out whether a program will perform a particular registration is equivalent to solving the stopping problem. Simpler tools like qmllint or qmlformat have no knowledge of C++ code and must parse your QML code in isolation. Therefore, they will not have any information about types registered in C++. To (partially) solve this problem, "qmltypes" files were introduced. When developing a QML plugin, it is recommended to place a file named "plugins.qmltypes" next to the plugin binary. The qmltypes file contains meta information about the types registered by the plugin. Qt Creator and other tools can then refer to this information to provide you with a better analysis of your code. It works, but only for plugins. If you are registering your types directly from the main program, you still run into the same problem. Also, you end up specifying your types twice, once in C++ and once in the qmltypes format. To (partially) solve the problem of redundant type specification, a tool called "qmlplugindump" is available. This tool will load your plugin just like the QML engine. It will then extract information about all the types it contains to create a plugins.qmltypes file. This will also allow unrelated code in your plugin to execute, and it will only work if you are compiling your plugin for the same platform that qmlplugindump is running on. In practice, this does not work for cross-compiled builds.
Given all these stumbling blocks, the type registration system has been redesigned in Qt 5.15. You should no longer call qmlRegisterType() and friends procedurally. Instead, a set of macros that you can add to class declarations is provided in qqml.h. These macros mark the type as exported to QML. The most important of these is "QML_ELEMENT". It provides a wrapper class in QML as an element named after the C++ class. The Meta Object Compiler (moc) will find the information specified in this way. When the "--output-json" option is passed, it provides a JSON file that contains all of the metatype information in a machine-independent and readable way. You can trigger this behavior by specifying "CONFIG += metatypes" in your qmake project file. A new tool named "qmltyperegistrar" then reads this metatype file and possibly related files and generates a C++ file containing a function that registers all types marked with the appropriate macros, as well as a qmltypes file with only type information relevant to QML module defined by your application. To do this, it needs to know the module name and major version. You can specify this in the qmake project file using the QML_IMPORT_NAME" and "QML_IMPORT_MAJOR_VERSION" variables. No minor version is specified. qmltyperegistrar will find fixed properties and methods in the metatype data and register different versions of the type accordingly. This determines the minor versions under which the module is available You can also make a type available from a specific minor version by adding the macro "QML_ADDED_IN_MINOR_VERSION(x)".
Once the build system is set up this way, you can initiate the actual registration by adding "CONFIG += qmltypes". The "qmltypes" CONFIG parameter implies "metatypes". You don't need to specify both.
This kind of static C++ type registration for QML will generate not only qmltypes files for plugins, but also for your main application. The latter files are called "app.qmltypes" and should be placed next to your application binary, just like "plugins.qmltypes" should be placed next to the plugin it refers to.
To illustrate this, let's convert an application that dynamically registers types to an application that statically registers the same types. This has already been done with all the QML and QtQuick examples. Let's look at a basic "Adding Types" example. In Qt 5.14 and earlier, the example had the following line of code in the main.cpp file:
qmlRegisterType<Person>("People", 1,0, "Person");
This will allow the C++ class "Person" to be registered as a QML element, also called "Person", in the "People" module in version 1.0. This line is gone in Qt 5.15. Instead, the following lines were added to the adding.pro file:
CONFIG += qmltypes QML_IMPORT_NAME = People QML_IMPORT_MAJOR_VERSION = 1
These lines specify the import name and major version for all types represented in QML. Finally, the most important change is the "QML_ELEMENT" macro added to the person.h file:
class Person : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize) QML_ELEMENT public: Person(QObject *parent = nullptr); [...] };
This "QML_ELEMENT" tells qmltyperegistrar to register the type. It's all. Now you can specify as many "QML_ELEMENT" as you want without typing version and revision import name each time.
У меня вот возник вопрос, как понимаю adding.pro дял добавления макросов это проектный файл?
А есть проект использует cmake, как там с этим обстоит?
Скорее всего также, как и для установки всех остальных переменых в CMake, через использование set