使用CMake创建Qt qml C ++插件

时间:2016-06-17 20:32:40

标签: c++ qt cmake qml

我尝试使用cmake创建C ++ qml插件(而不是使用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)

./包括/ Circle.hpp

#pragma once

#include <QObject>

namespace test {

class Circle: public QQuickItem {
    Q_OBJECT

public:
    Circle(QQuickItem* parent = nullptr);
    virtual ~Circle() = default;
};

} // namespace test

./包括/ Plugin.hpp

#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。每当我在主应用的qml文件中import CirclePlugin 1.0时,我都会收到module "Circle" is not installed消息。

我已经找到了关于该主题的以下指南,但我仍然不确定如何让它发挥作用。

QML Plugin Example

CMake Maunal

1 个答案:

答案 0 :(得分:1)

根据问题中的评论,我们发现QtQuick插件确实必须在被其他QtQuick应用程序或插件 * 找到并使用之前安装。这意味着:

  1. 插件必须位于自己的项目中,该项目由 Plugin.hpp 和(至少) qmldir 文件组成(假设插件.hpp 内置于名为 libcircleplugin.so 的插件库中,如下所示:

    module CirclePlugin
    plugin circleplugin
    
  2. 必须在QT_ROOT/QT_VERSION/ARCHITECTURE/qml/CirclePlugin/

  3. 内安装插件(即 libcircleplugin.so qmldir

    有关此程序的一些详细信息,请访问http://doc.qt.io/qt-5/qtqml-modules-cppplugins.html

    当然,这都是假设您将qmakecircle-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(请参阅What is the proper way of deploying C++ QML plugins on mobile device?),但通过将QML2_IMPORT_PATHQT_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中。这让我想到了下面的实际观点:

    在构建Qt插件/应用时,为什么qmake优先于cmake

    虽然我认为cmake不仅更为通用,而且完全是qmake的优秀构建系统,qmake仍然有时需要内部(例如QT_INSTALL_QML对于Qt及其应用程序/插件,Qt实际上是维护。对Qt的cmake的支持将永远是外部的(并且如Qt开发人员自己所说的那样“瘫痪”)。这意味着将来作为开发人员可能会有更多的维护负担,因为上述问题的解决方案可能会随着新版本随机破坏。

    我曾经梦想过使用cmake很好地构建我的Qt插件和应用程序,也可能会像https://github.com/taka-no-me/android-cmake那样使用.toolchain.cmake进行交叉编译。我很快发现它根本不值得做。