Создание плагина 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 / View.в QML

import QtQuick 2.2
import CirclePlugin 1.0

Item {

    Circle {
    }

}

я связываюсь с circle_plugin из моего основного приложения. Всякий Раз, Когда Я import CirclePlugin 1.0 в моем QML-файлы главного приложения, я получаю сообщение module "Circle" is not installed.

Я нашел следующие руководства по этой теме, но я все еще не уверен, как я могу заставить его работать.

пример плагина QML

CMake Maunal

1 ответов


после комментариев в вопросе мы узнали, что плагины QtQuick действительно должны быть установлены, прежде чем быть найдены и использованы другими приложениями или плагинами QtQuick *. Это означает, что:

  1. плагин должен быть в своем собственном проекте, который состоит из плагин.ГЭС и (по крайней мере)qmldir файл (при условии, что плагин.ГЭС встроен в библиотеку плагинов с именем libcircleplugin.так что) это выглядит так:

    module CirclePlugin
    plugin circleplugin
    
  2. плагин (i.e libcircleplugin.так что и qmldir) должен быть установлен внутри QT_ROOT/QT_VERSION/ARCHITECTURE/qml/CirclePlugin/

подробную информацию об этой процедуре можно найти по адресуhttp://doc.qt.io/qt-5/qtqml-modules-cppplugins.html

конечно, это все при условии, что вы используете qmake С circle-plugin.pro файл такой as:

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 заключается в том, что плагин не входит в АНК пока это не в QT_INSTALL_QML таким образом, окончательное приложение не может найти плагин; i.e он должен получить такое же лечение, как и другие официальные Плагины qml. Ручная установка и объединение усилий были бесплодны с нашей стороны, плагин просто не был найден во время выполнения, даже если вручную принудительно в apk (дойдя до написания custom 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'S, как https://github.com/taka-no-me/android-cmake. Я быстро понял, что это просто не стоит делать.