Сборка повторно используемого QML-модуля

Добавлено 2 января 2023 в 11:10

В приведенном ниже примере показано, как создать библиотеку, которая предоставляет C++ для QML. Структура каталогов этого примера выглядит так:

├── CMakeLists.txt
└── example
    └── mylib
        ├── CMakeLists.txt
        ├── mytype.cpp
        ├── mytype.h

Файл CMakeLists.txt верхнего уровня выполняет некоторую базовую настройку, а затем использует add_subdirectory для включения файла из mylib. Структура подкаталога соответствует URI модуля QML, но с заменой точек слешами. Это та же логика, которую движок использует при поиске модуля в путях импорта. mytype.h объявляет класс и использует макросы декларативной регистрации, чтобы представить его движку.

В подкаталоге CMakeLists.txt мы снова вызываем qt6_add_qml_module. Однако вызов немного отличается:

qt6_add_qml_module(mylib
    URI example.mylib
    VERSION 1.0
    SOURCES
        mytype.h mytype.cpp
)

Чтобы добавить типы C++, необходимо указать параметр SOURCES. Цель для mylib не создана. Поэтому, если цель, переданная в qt6_add_qml_module, не существует, автоматически создается цель библиотеки, которая необходима в данном случае.

При сборке проекта помимо библиотеки также собирается QML-плагин. Автоматически сгенерированный класс плагина наследуется от QQmlEngineExtensionPlugin. Сама библиотека mylib уже содержит код для регистрации типов в движке. Однако это полезно только в тех случаях, когда мы можем выполнить линковку с библиотекой. Чтобы модуль можно было использовать в файле QML, загруженном инструментом QML, необходим подключаемый плагин, который можно загрузить. Затем этот плагин отвечает за фактическое связывание с библиотекой и обеспечение регистрации типов.

Обратите внимание, что автоматическая генерация плагина возможна только в том случае, если модуль не делает ничего, кроме регистрации типов. Если вам нужно сделать что-то более сложное, например зарегистрировать поставщика изображений в initializeEngine, вам придется вручную написать плагин. qt6_add_qml_module поддерживает это с помощью NO_GENERATE_PLUGIN_SOURCE.

Кроме того, следование соглашению о структуре каталогов помогает инструментам. Эта структура отражается в каталоге сборки. Это означает, что вы можете передать инструменту QML путь к вашему каталогу сборки (через флаг -I), и он найдет плагин.

Прежде чем завершить, добавьте в модуль файл QML. В подкаталог lib добавьте файл Mistake.qml.

import example.mylib

MyType{
    answer: 43
}

и скорректируйте вызов qt6_add_qml_module:

qt6_add_qml_module(mylib
    URI example.mylib
    VERSION 1.0
    SOURCES
        mytype.h mytype.cpp
    QML_FILES
        Mistake.qml
)

Как уже упоминалось, мы допустили ошибку, потому что answer на самом деле является свойством только для чтения. Это иллюстрирует интеграцию с qmllint: CMake создает цель qmllint, и как только мы ее запускаем, qmllint предупреждает о проблеме:

$> cmake --build . --target mylib_qmllint
...
Warning: Mistake.qml:4:13: Cannot assign to read-only property answer
    answer: 43
            ^^

Теги

CMakeQMLQtПрограммированиеСистема сборки

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.