Создание плагина Qt qml C++ с помощью CMake
Я пытаюсь создать плагин c++ qml, используя cmake
(вместо использования QtCreator
). Вот фиктивный проект, имитирующий мою настройку плагина:
./ CMakeLists.txt
project(circle_plugin)
find_package(Qt5 COMPONENTS Core Qml Quick REQUIRED)
set(HEADERS
include/Circle.hpp
include/Plugin.hpp
)
add_library(circle_plugin STATIC ${HEADERS})
set_target_properties(circle_plugin PROPERTIES AUTOMOC ON)
target_link_libraries(circle_plugin PUBLIC Qt5::Core Qt5::Qml Qt5::Quick)
target_include_directories(circle_plugin PUBLIC include)
./ включить / круг.ГЭС
#pragma once
#include <QObject>
namespace test {
class Circle: public QQuickItem {
Q_OBJECT
public:
Circle(QQuickItem* parent = nullptr);
virtual ~Circle() = default;
};
} // namespace test
./ включить / плагин.ГЭС
#pragma once
#include <QObject>
namespace test {
class CirclePlugin : public QQmlExtensionPlugin {
Q_OBJECT
Q_PLUGIN_METADATA(IID "com.test.CirclePlugin")
public:
CirclePlugin();
~CirclePlugin();
void registerTypes(const char *uri) {
Q_ASSERT(uri == QLatin1String("CirclePlugin"));
qmlRegisterType<Circle>(uri, 1, 0, "Circle");
}
};
} // namespace test
./создания/просмотра.qml
import QtQuick 2.2
import CirclePlugin 1.0
Item {
Circle {
}
}
Я связываюсь с circle_plugin
из моего основного приложения. Всякий раз, когда я import CirclePlugin 1.0
в qml-файлах моего основного приложения, я получаю сообщение module "Circle" is not installed
.
Я нашел следующее руководство по теме, но я все еще не уверен, как я могу заставить его работать.
1 ответ:
Следуя комментариям в вопросе, мы выяснили, что плагины QtQuick действительно должны быть установлены, прежде чем быть найдены и использованы другими приложениями QtQuick или плагинами *. Это означает, что:
- Плагин должен быть в своем собственном проекте, который состоит из плагина .hpp и (по крайней мере) файл qmldir (предполагая, что плагин.hpp встроен в библиотеку плагинов с именем libcircleplugin.so ) что выглядит например:
module CirclePlugin plugin circleplugin
Плагин (то есть libcircleplugin.so и qmldir ) должны быть установлены внутри
QT_ROOT/QT_VERSION/ARCHITECTURE/qml/CirclePlugin/
Некоторые подробные сведения об этой процедуре можно найти в http://doc.qt.io/qt-5/qtqml-modules-cppplugins.html
Конечно, это все при условии, что вы используете
qmake
с файломcircle-plugin.pro
, таким как:QT += qml quick CONFIG += qt c++ nostrip plugin CONFIG -= android_install #If you care about Android HEADERS += Plugin.hpp TEMPLATE = lib TARGET = circleplugin TARGET = $$qtLibraryTarget($$TARGET) uri = CirclePlugin qmldir.files = qmldir OTHER_FILES += qmldir.files installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) qmldir.path = $$installPath target.path = $$installPath INSTALLS += target qmldir
С этим, вы можете
make install
и ваш плагин будет найден так же, как и любой другой модуль QtQuick, который есть и сами такие плагины. Эта процедура также должна быть воспроизведена с помощьюcmake
, если требуется аналогичное поведение. Для этого требуется знатьQT_INSTALL_QML
, который можно запросить, выполнивqmake -query QT_INSTALL_QML
. важное замечание : это не изолированный подход, так как он изменяет сам Qt SDK. Имейте в виду, что это зло, но также является лучшим решением в настоящее время.
* в то время как это верно для Android (см. каков правильный способ развертывания плагинов C++ QML на мобильном устройстве?), обойти эту проблему можно на рабочем столе, установив переменные окружения
QML2_IMPORT_PATH
илиQT_PLUGIN_PATH
в том месте, где вы установили свои плагины (ни один из которых не задокументирован; фактически, вся эта проблема до сих пор не задокументирована). Проблема с Android заключается в том, что плагин не входит в пакет apk, пока он не находится вQT_INSTALL_QML
, поэтому конечное приложение не может найти плагин; то есть он должен получить такое же лечение, как и другие официальные Плагины qml. Ручная установка и связывание усилий были безрезультатно с нашей стороны, плагин просто не был найден во время выполнения, даже если его вручную принудительно вставили в apk (дойдя до написания пользовательских файловandroid-libapplication.so-deployment-settings.json
для каждого приложения). Дискуссия (которая практически нигде не выходила за рамкиqmake -query QT_INSTALL_QML
) по этой теме находится в https://bugreports.qt.io/browse/QTBUG-29987 это подводит меня к моей фактической точке, которая находится ниже:
Почему
qmake
должно быть предпочтительнееcmake
при создании Qt плагинов/приложений?Хотя я считаю, что
cmake
является не только более общей, но и в целом более совершенной системой сборки, чтобыqmake
,qmake
все еще имеет внутренние компоненты, которые иногда необходимы (такие какQT_INSTALL_QML
) и фактически поддерживается Qt для Qt и его приложений/плагинов. Поддержкаcmake
для Qt всегда будет внешней (и" калечащей", как заявляют сами разработчики Qt). Это означает потенциально большую нагрузку по техническому обслуживанию в будущем на вашу сторону как разработчика, так как решения таких проблем, как выше, могут случайным образом ломаться с новыми версии.Я тоже когда-то мечтал о создании своих Qt плагинов и приложений красиво с
cmake
, а также, возможно, кросс-компиляции их с.toolchain.cmake
, как https://github.com/taka-no-me/android-cmake я быстро понял, что это просто не стоит делать.