Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. How to create static plugin using cmake?

How to create static plugin using cmake?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
1 Posts 1 Posters 1.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Maksym Kravchenko
    wrote on last edited by
    #1

    I wrote qml plugin using cmake. the source code is presented below. It works fine.
    Now I want built it as static plugin . I have added next changes in project.

    • add my plugin to link libraries in CMakeLists.txt
    target_link_libraries(
        ${PROJECT_NAME}
        PRIVATE
            Qt5::Core
            Qt5::Quick
            Qt5::Qml
            myplugin
    )
    
    • add plugin import to main.cpp
    #include <QtPlugin>
    Q_IMPORT_PLUGIN(MyPlugin)
    
    • build STATIC plugin version with QT_STATICPLUGIN difinition in my/plugin/CMakeLists.txt
    add_library(
        ${PLUGIN_NAME}
        STATIC
        Plugin.h
        QuickItem.h
        Plugin.cpp
        QuickItem.cpp
        plugin.qrc
        qmldir
    )
    
    target_compile_definitions(${PLUGIN_NAME}
        PUBLIC
          QT_STATICPLUGIN
    )
    
    • change plugin to classname i n qmldir
    classname Plugin
    

    Project is built fine but I have runtime error:
    QQmlApplicationEngine failed to load component
    qrc:/main.qml:11 MyQuickItem is not a type

    QML engine parses "import my.plugin 1.0" it's mean qmldir is found
    But MyPlugin::registerTypes is never called (I think for calling this function need add classname to qmldir but unfortunately it doesn't work ). I have checked this code with Qt 5.12.4 and 5.15.1, result is same.
    What else should I do?

    My file system:

    ┣━ CMakeLists.txt
    ┣━ app.qrc
    ┣━ main.cpp
    ┣━ main.qml
    ┗━ my
        ┗━ plugin
            ┣━ CMakeLists.txt
            ┣━ MyButton.qml
            ┣━ Plugin.cpp
            ┣━ Plugin.h
            ┣━ QuickItem.cpp
            ┣━ QuickItem.h
            ┣━ plugin.qrc
            ┗━ qmldir
    

    CMakeLists.txt:

    cmake_minimum_required(VERSION 3.0)
    project(app VERSION 1.0 LANGUAGES CXX)
    
    find_package(Qt5 REQUIRED COMPONENTS Quick Core Qml)
    
    add_executable(
        ${PROJECT_NAME}
        main.cpp
        app.qrc
    )
    
    set_target_properties(
        ${PROJECT_NAME}
        PROPERTIES
            AUTOMOC ON
            AUTORCC ON
    )
    
    target_link_libraries(
        ${PROJECT_NAME}
        PRIVATE
            Qt5::Core
            Qt5::Quick
            Qt5::Qml
    )
    
    add_subdirectory(my/plugin)
    

    app.qrc

    <RCC>
        <qresource prefix="/">
            <file>main.qml</file>
        </qresource>
    </RCC>
    

    main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    
    int main(int argc, char *argv[]) {
    
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine;
    
        engine.load(QUrl(QLatin1String("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty()) {
            return -1;
        }
        return app.exec();
    }
    

    main.qml

    import QtQuick.Controls 2.0
    import my.plugin 1.0
    
    ApplicationWindow {
        visible: true
        width: 640
        height: 480
        title: "Lyzer"
    
        // 'myplugin' C++ class
        MyQuickItem {
            id: pluginItem
            color: "green"
            width: 100
            height: 50
            anchors.centerIn: parent
        }
    
        // 'myplugin' QML file
        MyButton {
            anchors.top: pluginItem.bottom
            anchors.horizontalCenter: pluginItem.horizontalCenter
            width: pluginItem.width
            onClicked: {
                pluginItem.color = '#' + Math.floor(Math.random() * 0x1000000).toString(16);
            }
        }
    }
    

    CMakeLists.txt for plugin

    set(PLUGIN_NAME myplugin)
    
    add_library(
        ${PLUGIN_NAME}
        SHARED
        Plugin.h
        QuickItem.h
        Plugin.cpp
        QuickItem.cpp
        plugin.qrc
        qmldir
    )
    
    set_target_properties(
        ${PLUGIN_NAME}
        PROPERTIES
            AUTOMOC ON
            AUTORCC ON
    )
    
    target_link_libraries(
        ${PLUGIN_NAME}
        PRIVATE
            Qt5::Core
            Qt5::Quick
            Qt5::Qml
    )
    
    add_custom_command(
        TARGET ${PLUGIN_NAME}
        POST_BUILD
        COMMAND
            ${CMAKE_COMMAND} -E copy
            ${CMAKE_CURRENT_LIST_DIR}/qmldir
            $<TARGET_FILE_DIR:myplugin>/qmldir
    )
    

    MyButton.qml

    import QtQuick.Controls 2.0
    
    Button {
        text: "Click me!"
    }
    

    Plugin.cpp

    #include "Plugin.h"
    #include "QuickItem.h"
    
    void MyPlugin::registerTypes(const char* uri) {
        qmlRegisterType<My::QuickItem>(uri, 1, 0, "MyQuickItem");
    }
    

    plugin.h

    #pragma once
    
    #include <QtQml/QQmlExtensionPlugin>
    
    class MyPlugin: public QQmlExtensionPlugin {
        Q_OBJECT
        Q_PLUGIN_METADATA(IID "my.plugin/1.0")
    public:
        void registerTypes(const char* uri) override;
    };
    

    QuickItem.cpp

    #include "QuickItem.h"
    
    #include <QPen>
    #include <QPainter>
    
    namespace My {
    QuickItem::QuickItem(QQuickItem* parent)
        : QQuickPaintedItem(parent) {
    }
    
    QColor QuickItem::getColor() const {
        return color;
    }
    
    void QuickItem::setColor(const QColor& color) {
        if (color != this->color) {
            this->color = color;
            update();
            emit colorChanged();
        }
    }
    
    void QuickItem::paint(QPainter* painter) {
        QPen pen(color, 2);
        painter->setPen(pen);
        painter->fillRect(QRectF(0, 0, width(), height()), color);
    }
    }
    

    QuickItem.h

    #pragma once
    
    #include <QtQuick/QQuickPaintedItem>
    #include <QColor>
    
    namespace My {
    class QuickItem: public QQuickPaintedItem {
        Q_OBJECT
        Q_PROPERTY(QColor color READ getColor WRITE setColor NOTIFY colorChanged)
    public:
        QuickItem(QQuickItem* parent = nullptr);
        QColor getColor() const;
        void setColor(const QColor &color);
        void paint(QPainter *painter) override;
    
    signals:
        void colorChanged();
    
    private:
        QColor color;
    };
    }
    

    plugin.qrc

    <RCC>
        <qresource prefix="/plugin">
            <file>MyButton.qml</file>
        </qresource>
    </RCC>
    

    qmldir

    module my.plugin
    plugin myplugin
    MyButton 1.0 qrc:/plugin/MyButton.qml
    
    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved