mafulechka
mafulechka26 березня 2020 р. 05:18

Реєстрація типу QML у Qt 5.15

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", скільки захочете, щоразу не набираючи ім'я імпорту версії та ревізії.

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

BlinCT
  • 26 березня 2020 р. 10:50

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

Evgenii Legotckoi
  • 27 березня 2020 р. 04:36

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

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
d
  • dsfs
  • 26 квітня 2024 р. 11:56

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80бали,
  • Рейтинг балів4
d
  • dsfs
  • 26 квітня 2024 р. 11:45

C++ - Тест 002. Константы

  • Результат:50бали,
  • Рейтинг балів-4
d
  • dsfs
  • 26 квітня 2024 р. 11:35

C++ - Тест 001. Первая программа и типы данных

  • Результат:73бали,
  • Рейтинг балів1
Останні коментарі
k
kmssr09 лютого 2024 р. 02:43
Qt Linux - Урок 001. Автозапуск програми Qt під Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко05 лютого 2024 р. 09:50
Qt WinAPI - Урок 007. Робота з ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25 грудня 2023 р. 18:30
Boost - статичне зв&#39;язування в проекті CMake під Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJo25 грудня 2023 р. 16:38
Boost - статичне зв&#39;язування в проекті CMake під Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
Gvozdik19 грудня 2023 р. 05:01
Qt/C++ - Урок 056. Підключення бібліотеки Boost в Qt для компіляторів MinGW і MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Тепер обговоріть на форумі
Evgenii Legotckoi
Evgenii Legotckoi02 травня 2024 р. 21:07
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.
IscanderChe
IscanderChe30 квітня 2024 р. 11:22
Во Flask рендер шаблона не передаётся в браузер Доброе утро! Имеется вот такой шаблон: <!doctype html><html> <head> <title>{{ title }}</title> <link rel="stylesheet" href="{{ url_…
G
Gar22 квітня 2024 р. 12:46
Clipboard Как скопировать окно целиком в clipb?
Павел Дорофеев
Павел Дорофеев14 квітня 2024 р. 09:35
QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
f
fastrex04 квітня 2024 р. 11:47
Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…

Слідкуйте за нами в соціальних мережах