Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved How to create static plugin using cmake?

    QML and Qt Quick
    1
    1
    888
    Loading More Posts
    • 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
      Maksym Kravchenko last edited by

      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 Reply Quote 0
      • First post
        Last post