Регистрация типа QML в Qt 5.15

qmlRegisterType, QMetaType, qmlRegisterSingletonType, Qt, QML, QML_ELEMENT

Qt 5.15 предоставляет значительно улучшенный способ представления типов C++ для QML. Теперь вы можете указать имя и версию вашего модуля в центральном месте, и больше не нужно указывать минорные версии или ревизии. Кроме того, специфика регистрации типа QML теперь может быть заявлена в объявлении класса C++.

До сих пор распространенным способом обеспечения доступности типов C++ в QML было использование функций регистрации, представленных в заголовке qqml.h header: qmlRegisterType(), qmlRegisterSingletonType(), qmlRegisterUncreatableType() и т. д. У этого подхода есть свои недостатки:

вы всегда должны держать свои регистрации типов в синхронизации с фактическими типами. Это особенно утомительно, если вы используете ревизии, чтобы сделать свойства доступными в разных версиях импорта. Даже если это не так, тот факт, что вам нужно указывать регистрацию отдельно от типа, является обременительным, поскольку вы можете легко потерять учет того, как вы регистрировали, какие типы в какие модули.

Кроме того, поскольку вы регистрируете свои типы процедурно, любой инструмент QML не может автоматически определить, какие типы доступны в каком импорте. Qt Creator действительно имеет некоторые эвристические методы, которые пытаются обнаружить общие шаблоны регистрации в коде C++, но это является неполным. Выяснение того, будет ли программа выполнять определенную регистрацию, эквивалентно решению проблемы остановки. Более простые инструменты, такие как qmllint или qmlformat, не имеют информации о коде C++ и должны анализировать ваш код QML изолированно. Поэтому у них не будет никакой информации о типах, зарегистрированных в C++. Чтобы (частично) решить эту проблему, были введены файлы "qmltypes". При разработке плагина QML рекомендуется поместить файл с именем "plugins.qmltypes" рядом с двоичным файлом плагина. Файл qmltypes содержит метаинформацию о типах, зарегистрированных плагином. Qt Creator и другие инструменты могут затем обратиться к этой информации, чтобы предоставить вам лучший анализ вашего кода. Это работает, но только для плагинов. Если вы регистрируете свои типы непосредственно из основной программы, вы все еще сталкиваетесь с той же проблемой. Кроме того, вы заканчиваете указанием ваших типов дважды, один раз в C++ и один раз в формате qmltypes. Чтобы (частично) решить проблему избыточной спецификации типа, доступен инструмент под названием "qmlplugindump". Этот инструмент загрузит ваш плагин так же, как и механизм QML. Затем он извлечет информацию обо всех типах, содержащихся в нем, для создания файла plugins.qmltypes. Это также позволит выполнить несвязанный код в вашем плагине, и он будет работать, только если вы компилируете свой плагин для той же платформы, на которой работает qmlplugindump. На практике это не работает для кросс-скомпилированных сборок.

Учитывая все эти камни преткновения, система регистрации типов была переработана в Qt 5.15. Вы не должны больше вызывать qmlRegisterType() и друзей процедурно. Вместо этого набор макросов, которые вы можете добавить в объявления классов, предоставляется в qqml.h. Эти макросы помечают тип как экспортированный в QML. Наиболее важным из них является "QML_ELEMENT". Он предоставляет класс обёртку в QML как элемент, названный именем класса C++. Компилятор мета-объектов (moc) найдет информацию, указанную таким образом. Когда передается параметр "--output-json", он предоставляет файл JSON, который содержит всю информацию метатипа в машинно-независимом и читаемом виде. Вы можете запустить это поведение, указав "CONFIG += metatypes" в вашем файле проекта qmake. Затем новый инструмент с именем "qmltyperegistrar" считывает этот файл метатипов и, возможно, связанные с ним файлы, и генерирует файл C++, содержащий функцию, которая регистрирует все типы, отмеченные соответствующими макросами, а также файл qmltypes только с информацией о типе, релевантной для модуля QML определенной вашим приложением. Для этого ему необходимо знать имя модуля и основную версию. Вы можете указать это в файле проекта qmake, используя переменные QML_IMPORT_NAME" и "QML_IMPORT_MAJOR_VERSION". Минорная версия не указывается. qmltyperegistrar найдет исправленные свойства и методы в данных метатипа и, соответственно, зарегистрирует разные версии типа. Это определяет минорные версии, под которыми доступен модуль. Вы также можете сделать тип доступным из определенной минорной версии, добавив макрос "QML_ADDED_IN_MINOR_VERSION(x)".

Как только система сборки настроена таким образом, вы можете инициировать фактическую регистрацию, добавив "CONFIG += qmltypes". Параметр "qmltypes" CONFIG подразумевает "metatypes". Вам не нужно указывать оба.

Такая статическая регистрация типов C++ для QML будет генерировать не только файлы qmltypes для плагинов, но и для вашего основного приложения. Последние файлы называются "app.qmltypes" и должны быть расположены рядом с двоичным файлом вашего приложения, точно так же, как "plugins.qmltypes" должен быть расположен рядом с плагином, на который он ссылается.

Чтобы проиллюстрировать это, давайте преобразуем приложение, которое динамически регистрирует типы, в приложение, которое статически регистрирует те же типы. Это уже было сделано со всеми примерами QML и QtQuick. Давайте посмотрим на основной пример "Adding Types" ("Добавление типов"). В Qt 5.14 и ранее у примера была следующая строка кода в файле main.cpp:

qmlRegisterType<Person>("People", 1,0, "Person");

Это позволит зарегистрировать C++ class "Person" в качестве элемента QML, также называемого "Person", в модуле "People" в версии 1.0. Эта строка исчезла в Qt 5.15. Вместо этого в файл adding.pro были добавлены следующие строки:

CONFIG += qmltypes
QML_IMPORT_NAME = People
QML_IMPORT_MAJOR_VERSION = 1

Эти строки указывают имя импорта и основную версию для всех типов, представленных в QML. Наконец, наиболее важным изменением является макрос "QML_ELEMENT", добавленный в файл person.h:

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);
    [...]
};

Этот "QML_ELEMENT" указывает qmltyperegistrar, чтобы зарегистрировать тип. Это все. Теперь вы можете указать столько "QML_ELEMENT", сколько захотите, каждый раз не набирая имя импорта версии и ревизии.

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.
Support the author Donate

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

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

Comments

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

Hello, Dear Users of EVILEG!!!

If the site helped you, then support the development of the site financially, please.

You can do it by following ways:

Thank you, Evgenii Legotckoi

A
April 6, 2020, 5:24 a.m.
Alexey

C++ - Test 001. The first program and data types

  • Result:86points,
  • Rating points6
R
April 5, 2020, 2:32 p.m.
Roman

C++ - Test 002. Constants

  • Result:91points,
  • Rating points8
AP
April 5, 2020, 2:31 p.m.
Alexander Peshkov

C++ - Test 001. The first program and data types

  • Result:60points,
  • Rating points-1
Last comments
April 3, 2020, 8:06 a.m.
Konstantin Grudnitskiy

Я надеюсь вы уже разобрались в чем дело, но если вдруг нет, то проблема состоит в том, что вы пытаетесь запустить программу из интерпретатора питона. Файл main.py это уже готова…
April 3, 2020, 6:18 a.m.
Konstantin Grudnitskiy

>>> text = 'hello world'>>> ' '.join(word for word in text.split()[:-1])'hello'>>> def remove_last_word(text):... return text and ' '.join(word for word in text.s…
March 27, 2020, 2:40 p.m.
Evgenij Legotskoj

Добрый день. В конце пятой статьи скачать можете.
March 27, 2020, 2:28 p.m.
mkdir _

Здравствуйте, а можно, пожалуйста, ссылку на целые исходники, если есть?
March 27, 2020, 4:36 a.m.
Evgenij Legotskoj

Скорее всего также, как и для установки всех остальных переменых в CMake, через использование set
Now discuss on the forum
s
April 6, 2020, 8:06 a.m.
shuric

Добрый день. Объясните пожалуйста ... ... допиливать стилевое оформление в прокси классе ... где именно копать ? В каком виртуальном методе лучше допиливать (если можно н…
April 6, 2020, 4:19 a.m.
Evgenij Legotskoj

Попробуй не переустанавливать материал, а просто менять цвет
April 5, 2020, 11:38 a.m.
Mihailll

Так работает windeployqt --qmldir E:\QTProject\testQmlAndCpp E:\test\build-testQmlAndCpp-Desktop_Qt_5_14_1_MinGW_32_bit-Release
April 5, 2020, 2:35 a.m.
Mihailll

Так работает console.log(textEmail.text) var str = textEmail.text; var n = str.search(/^((([0-9A-Za-z]{1}[-0-9A-z\.]{1,}[0-9A-Za-z]{1})|([0-9А-Яа-я]{1}[-0-9А-я\.]{1,}[…
April 3, 2020, 8:48 a.m.
Intruder

Евгений, добрый день. Спасибо!
EVILEG
About
Services
© EVILEG 2015-2019
Recommend hosting TIMEWEB