mafulechka
mafulechkaMarch 26, 2020, 5:18 a.m.

QML Type Registration in Qt 5.15

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.

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

BlinCT
  • March 26, 2020, 10:50 a.m.

У меня вот возник вопрос, как понимаю adding.pro дял добавления макросов это проектный файл?
А есть проект использует cmake, как там с этим обстоит?

Evgenii Legotckoi
  • March 27, 2020, 4:36 a.m.

Скорее всего также, как и для установки всех остальных переменых в CMake, через использование set

Comments

Only authorized users can post comments.
Please, Log in or Sign up
AD

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
m

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:80points,
  • Rating points4
m

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:20points,
  • Rating points-10
Last comments
ИМ
Игорь МаксимовNov. 22, 2024, 8:51 a.m.
Django - Tutorial 017. Customize the login page to Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii LegotckoiOct. 31, 2024, 11:37 a.m.
Django - Lesson 064. How to write a Python Markdown extension Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZEOct. 19, 2024, 5:19 a.m.
Fb3 file reader on Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь МаксимовOct. 5, 2024, 4:51 a.m.
Django - Lesson 064. How to write a Python Markdown extension Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas5July 5, 2024, 8:02 a.m.
QML - Lesson 016. SQLite database and the working with it in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Now discuss on the forum
Evgenii Legotckoi
Evgenii LegotckoiJune 24, 2024, 12:11 p.m.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey1Nov. 15, 2024, 3:04 a.m.
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProjectJune 4, 2022, 12:49 a.m.
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9AnonimOct. 25, 2024, 6:10 a.m.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Follow us in social networks