mafulechka
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 хостинг.

Вам это нравится? Поделитесь в социальных сетях!

BlinCT
  • 26 марта 2020 г. 10:50

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

Evgenii Legotckoi
  • 27 марта 2020 г. 4:36

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

Комментарии

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

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

  • Результат:50баллов,
  • Очки рейтинга-4
m
  • molni99
  • 26 октября 2024 г. 1:37

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

  • Результат:80баллов,
  • Очки рейтинга4
m
  • molni99
  • 26 октября 2024 г. 1:29

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

  • Результат:20баллов,
  • Очки рейтинга-10
Последние комментарии
ИМ
Игорь Максимов22 ноября 2024 г. 11:51
Django - Урок 017. Кастомизированная страница авторизации на Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii Legotckoi31 октября 2024 г. 14:37
Django - Урок 064. Как написать расширение для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZE19 октября 2024 г. 8:19
Читалка fb3-файлов на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь Максимов5 октября 2024 г. 7:51
Django - Урок 064. Как написать расширение для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55 июля 2024 г. 11:02
QML - Урок 016. База данных SQLite и работа с ней в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Сейчас обсуждают на форуме
m
moogo22 ноября 2024 г. 7:17
Mosquito Spray System Effective Mosquito Systems for Backyard | Eco-Friendly Misting Control Device & Repellent Spray - Moogo ; Upgrade your backyard with our mosquito-repellent device! Our misters conce…
Evgenii Legotckoi
Evgenii Legotckoi24 июня 2024 г. 15:11
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey115 ноября 2024 г. 6:04
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProject4 июня 2022 г. 3:49
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…

Следите за нами в социальных сетях