1

I'm trying to create simple QML C++ plugin using CMake. There are my sources:

CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.12)

project(qmltest LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

# Path to installed Qt 5.15
set(Qt5Core_DIR ".../Qt/5.15.0/gcc_64/lib/cmake/Qt5Core")
set(Qt5Qml_DIR ".../Qt/5.15.0/gcc_64/lib/cmake/Qt5Qml")
set(Qt5Quick_DIR ".../Qt/5.15.0/gcc_64/lib/cmake/Qt5Quick")

find_package(Qt5 COMPONENTS Core Quick Qml REQUIRED)

LINK_DIRECTORIES(.../Qt/5.15.0/gcc_64/lib)
INCLUDE_DIRECTORIES(.../Qt/5.15.0/gcc_64/include)
INCLUDE_DIRECTORIES(.../Qt/5.15.0/gcc_64/include/QtQml)
set(QML_IMPORT_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE STRING "" FORCE)

add_library(dummy SHARED
  "dummy.h" "dummy.cpp" "myplugin.h" "myplugin.cpp"
)
target_link_libraries(dummy Qt5::Core Qt5::Quick Qt5::Qml)

add_executable(${PROJECT_NAME} "main.cpp" "qml.qrc")

target_link_libraries(${PROJECT_NAME} dummy Qt5::Core Qt5::Quick Qt5::Qml)

main.cpp:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QObject>
#include <QtPlugin>

int main(int argc, char *argv[])
{
  qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));

  QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

  QGuiApplication app(argc, argv);

  QQmlApplicationEngine engine;
  engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
  if (engine.rootObjects().isEmpty())
    return -1;

  return app.exec();
}

dummy.h:

#ifndef DUMMY_H
#define DUMMY_H

#include <QObject>

class Dummy : public QObject
{
  Q_OBJECT
  Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)

public:
  explicit Dummy(QObject *parent = nullptr);
  QString name();
  void setName(const QString x);

signals:
  void nameChanged();

public slots:

private:
  QString _name;
};

#endif // DUMMY_H


myplugin.h:

#ifndef MYPLUGIN_H
#define MYPLUGIN_H

#include <QtQml/QQmlEngineExtensionPlugin>
#include <QObject>
#include <QQmlApplicationEngine>
#include <iostream>

#include <dummy.h>

class MyPlugin : public QQmlEngineExtensionPlugin
{
  Q_OBJECT
  Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)

public:
  void registerTypes(const char* uri) {
     std::cout << "GGGGGGGGGGGGGGGG\n";
     qmlRegisterType<Dummy>(uri, 1, 0, "Dummy");
     qmlRegisterModule(uri, 1, 0);
     qmlProtectModule(uri, 1);
  }
};

#endif // MYPLUGIN_H

main.qml:

import MyPlugin 1.0

Window {
    Dummy {}
}

I also created directory in my build directory named MyPlugin with link to built libdummy.so and qmldir file as below:

module MyPlugin
plugin dummy

Project builds, but when I run it, I get an error:

plugin cannot be loaded for module "MyPlugin": Cannot protect module MyPlugin 1 as it was never registered

My debug output from registerTypes function have not been called (no output on stdout), so I assume that types have not been registered by some reasons. If I try register type statcally by add this line to myplugin.cpp:

static int unused = qmlRegisterType<Dummy>("MyPlugin", 1, 0, "Dummy");

, I get an error:

plugin cannot be loaded for module "MyPlugin": Namespace 'MyPlugin' has already been used for type registration

What do I wrong in this plugin and how to make it works with CMake?

1
  • By the Qt docs the syntax should be plugin <Name> [<Path>] where <Name> is the plugin library name. You've provided type name instead. Commented Jul 14, 2020 at 11:03

2 Answers 2

2

Qt contains 2 different base class for qml plugins: QQmlEngineExtensionPlugin (This class was introduced in Qt 5.14) and QQmlExtensionPlugin

myplugin.h:

#ifndef MYPLUGIN_H
#define MYPLUGIN_H

#include <QtQml/QQmlExtensionPlugin>
#include "dummy.h"

class MyPlugin : public QQmlExtensionPlugin
{
  Q_OBJECT
  Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)

public:
  void registerTypes(const char* uri) {
     qmlRegisterType<Dummy>(uri, 1, 0, "Dummy");
  }
};

#endif // MYPLUGIN_H
Sign up to request clarification or add additional context in comments.

Comments

1

as of Qt 6.2, the plugin class is generated for you by qt6_add_qml_module:

https://doc.qt.io/qt-6/cmake-build-reusable-qml-module.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.