c++qtqmlqqmlengine

Develop own QQmlExtensionPlugin: module not installed when trying to use in a sample-project


I am trying to create a QQmlExtensionPlugin to use it in another application as a qml-module.

The problem I have is, that when I compile the project and try to use it in a sample-project the qml-compiler says, that the module "Clock 1.0" is not installed and cannot be loaded. Does anyone know what to do in this situation? You can find the full source-code here: https://github.com/MhouneyLH/qml_cpp_examples on the branch "feat/model_adjustments".

In Summary, what did I do to compile the plugin:

  1. Add qml-files (in the repository under example_transformation/qml/Clock), which should be part of the plugin.
  2. Add a qmldir-file
module Clock
plugin clockplugin
  1. Create Plugin.h (and the corresponding Plugin.cpp-file -> in my case it is not needed, since for now I don't want to create a cpp-backend) for the meta-information of the plugin.
#ifndef CLOCKPLUGIN_H
#define CLOCKPLUGIN_H

#include <QQmlExtensionPlugin>

class ClockPlugin : public QQmlExtensionPlugin
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)

public:
    void registerTypes(const char* uri);
};

#endif // CLOCKPLUGIN_H
  1. Adjust the .pro-file of the project
TEMPLATE = lib
CONFIG += plugin
QT += quick qml

DESTDIR = ../Clock
TARGET = clockplugin

SOURCES += \
        src/ClockPlugin.cpp \
        src/main.cpp

HEADERS += \
    src/ClockPlugin.h

RESOURCES += qml/qml.qrc

DISTFILES += \
    qml/Clock/qmldir

DESTPATH = qml/Clock

target.path = $$DESTPATH
qmldir.files = $$DESTPATH/qmldir
qmldir.path = $$DESTPATH
INSTALLS += target qmldir

CONFIG += install_ok  # Do not cargo-cult this!

# Copy the qmldir file to the same folder as the plugin binary
QML_DIR = qml/Clock
resource.files += \
    $$QML_DIR/qmldir \
    $$QML_DIR/Clock.qml \
    $$QML_DIR/ClockBackground.qml \
    $$QML_DIR/GenericClockHand.qml \
    $$QML_DIR/HourClockHand.qml \
    $$QML_DIR/MinuteClockHand.qml \
    $$QML_DIR/SecondClockHand.qml
resource.path = $$DESTDIR
COPIES += resource
INSTALLS += resource
  1. Compile the project.

But how do I bring the compiled plugin into the sample-project? (sry, I have to few reputation to show images directly)

  1. All needed qml-files, the qmldir and the .dll is in the plugin-folder "Clock" (see here: https://i.sstatic.net/B3P0Q.jpg)
  2. Copy this folder to sample-project/build/ after the sample-project compiled 1 time (so the directory is created) (see here: https://i.sstatic.net/MuhZ0.jpg)
  3. In the qml-file I just want to use the module like that
import QtQuick 2.15
import QtQuick.Window 2.15
import Clock 1.0

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    Clock {
        id: clock
    }
}

As it is documented it is enough to have this folder next to the .exe of my sample-project.

I already tried to set QML_IMPORT_PATH and QML2_IMPORT_PATH in the sample-project .pro-file. This unfortunately did not work as expected.

Besides that I tried some things from this thread.


Solution

  • I finally got it. The hints of @Stephen Quan are pretty good. I ended up cleaning my whole .pro-file an rewrite it but this time only with the for me relevant stuff:

    QT += qml
    TEMPLATE = lib
    CONFIG += qt plugin qmltypes
    
    QML_IMPORT_NAME = ClockPlugin
    QML_IMPORT_MAJOR_VERSION = 1
    
    DESTDIR = imports/$$QML_IMPORT_NAME
    TARGET  = clockplugin
    
    RESOURCES += qml/plugin_qml.qrc
    
    SOURCES += \
        src/ClockPlugin.cpp
    
    HEADERS += \
        src/ClockPlugin.h
    
    # copying dependecies of the plugin in the output-folder
    PLUGIN_DEPENDENCY_DIRECTORY = $$PWD/qml/Clock
    PluginDependencies.commands = $(COPY_DIR) $$shell_path($$PLUGIN_DEPENDENCY_DIRECTORY) $$shell_path($$DESTDIR)
    
    first.depends = $(first) PluginDependencies
    export(first.depends)
    export(PluginDependencies)
    QMAKE_EXTRA_TARGETS += first PluginDependencies
    

    So with this I can then import the module with import ClockPlugin 1.0. The other things I mentioned in my question are still the same. (qmldir-file, etc.)