Сборка повторно используемого QML-модуля
В приведенном ниже примере показано, как создать библиотеку, которая предоставляет 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
^^