mafulechka26 марта 2020 г. 5: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 хостинг.
Поддержать автора Donate
  • #
  • 26 марта 2020 г. 10:50

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

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

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
Card image cap
Pulsum Via

Проект для путешественников от EVILEG.

Перейти
Timeweb

Позвольте мне порекомендовать вам отличный хостинг, на котором расположен EVILEG.

В течение многих лет Timeweb доказывает свою стабильность.

Для проектов на Django рекомендую VDS хостинг

Посмотреть Хостинг
Поделиться в социальных сетях
Donate

Проект EVILEG перешёл на некоммерческую основу и будет развиваться исключительно на энтузиазме создателя сайта, энтузиазме пользователей, пожертвованиях и реферальной системе хостинга

Спасибо за вашу поддержку

Доступные способы поддержки проекта

PayPal

PatreonYooMoneyПодробнее
s

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

  • Результат:50баллов,
  • Очки рейтинга-4
s

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

  • Результат:66баллов,
  • Очки рейтинга-1
r

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

  • Результат:58баллов,
  • Очки рейтинга-2
Последние комментарии

Qt/C++ - Урок 061. Добавление изображений в приложение методом Drag And Drop из файлового менеджера

Доброго времени суток. А если нужно и изображение и текст? Что-то потерялся немного.... // Вместо отрисовки иконки и текста будем отрисовывать только одно изображение // с н…
АС

Qt/C++ - Урок 004. QSqlTableModel или Как представить таблицу из БД в Qt?

error insert into TableExample " Количество параметров не совпадает" Я путь свой прописывала и даже бд удаляла, чтобы заново сделать, не работает. (всё остальное как у вас... Вроде ка…
i
ЛД

GameDev на Qt - Урок 1. Отслеживание перемещения мыши в QGraphicsScene

Вполне возможно, что ты не закинул graphicsView в дизайнере в виджет
ЛД

GameDev на Qt - Урок 1. Отслеживание перемещения мыши в QGraphicsScene

Кому интересно, поворот в slotTarget можно в одну строку организовать this->setRotation(90 + rotation() + qRadiansToDegrees(qAtan2(mapFromScene(point).y(), mapFromScene(point).x())));
Сейчас обсуждают на форуме
K

Sorting the added QML elements in the ListModel

buy accutane online forum https://isotretinoinxp.top
  • Nomad
  • 30 июля 2022 г. 5:42

Как работать с HTMX?

Приветствую колеги. На днях наткнулся на вот это : https://htmx.org/ На офф сайте написанно вот такая фраза: htmx gives you access to AJAX, CSS Transitions, We…
h
  • harisr
  • 25 июля 2022 г. 2:56

QT - Native App Integration

Привет, у нас уже есть собственное приложение для Android. Можем ли мы интегрировать пользовательское представление QT в приложение со всем приложением QT внутри представления. Если да, ука…

Правильный запуск сервера на vps - Django

О я как то себе дома локальный сервер создавал. Вам же нужно просто сделать ручками конфигурацию системы. Настроить Nginx ну либо Apache (тут кому что нравится). Соответственно БД и всё остально…
o

Распознание объектов

Я к тому, что, возможно, софт уже есть.
О нас
Услуги
© EVILEG 2015-2022
Рекомендует хостинг TIMEWEB