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", скільки захочете, щоразу не набираючи ім'я імпорту версії та ревізії.
У меня вот возник вопрос, как понимаю adding.pro дял добавления макросов это проектный файл?
А есть проект использует cmake, как там с этим обстоит?
Скорее всего также, как и для установки всех остальных переменых в CMake, через использование set