Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[Solved] Problem with QML Extension



  • Hi!

    I'm currently have a problem with using a QML Extension.

    I'm working on a project that consists of an QML Application and an QML Extension Plugin. In the Plugin I have (only) C++ classes that should be used in the Application.
    Let's say the application's project name is QMLApplication and the library's project name QMLExtension then my folder structure looks like this:
    @
    D:\Projects\Qt
    |-- QMLApplication
    |-- Build
    |-- QMLApplication
    |-- Desktop_Qt_5_2_0_MSVC2012_32bit
    |-- debug
    |-- QMLApplication.exe
    |-- QMLExtension
    |-- Desktop_Qt_5_2_0_MSVC2012_32bit
    |-- debug
    |-- QMLPlugind.dll
    |-- qmldir
    |-- QMLApplication
    |-- qml
    |-- Window
    |-- Window.qml
    |-- Main.cpp
    |-- QtGUI.qrc
    |-- QMLApplication.pro
    |-- QMLExtension
    |-- CppClass.cpp
    |-- CppClass.hpp
    |-- qmldir
    |-- QMLExtensionPlugin.cpp
    |-- QMLExtensionPlugin.hpp
    @

    QMLApplication.pro:
    @QT += qml quick

    qmlfoler.source = qml
    qmlfoler.target = qml
    DEPLOYMENTFOLDERS = qmlfoler

    Additional import path used to resolve QML modules in Creator's code model

    QML_IMPORT_PATH =

    Source files.

    SOURCES +=
    Main.cpp

    Target

    TARGET = QMLApplication

    Resource files.

    RESOURCES +=
    QtGUI.qrc

    Librarys.

    win32:CONFIG(release, debug|release):LIBS += -L$$PWD/../Build/QMLExtension/Desktop_Qt_5_2_0_MSVC2012_32bit/release -lQMLExtension
    }
    else:win32:CONFIG(debug, debug|release):LIBS += -L$$PWD/../Build/QMLExtension/Desktop_Qt_5_2_0_MSVC2012_32bit/debug -lQMLExtensiond
    }
    #else:unix: LIBS += -L$$PWD/?/ -QMLExtension

    Include- and dependpaths.

    INCLUDEPATH += $$PWD/../QMLExtension
    DEPENDPATH += $$PWD/../QMLExtension

    OTHER_FILES +=
    qml/Window/Window.qml
    @
    Main.cpp:
    @#include <QtGui/QGuiApplication>
    #include <QtQml>

    #include <CppClass.hpp>

    int main(int argc, char *argv[])
    {
    QGuiApplication app(argc, argv);

    QByteArray data = "1";
    qputenv("QML_IMPORT_TRACE", data);
    
    QQmlApplicationEngine engine;
    engine.load(QUrl("qrc:/qml/Window/Window.qml"));
    
    return app.exec&#40;&#41;;
    

    }@

    QMLExtension.pro:
    @TEMPLATE = lib
    TARGET = QMLExtension
    QT -= gui
    QT += qml
    CONFIG += qt plugin

    TARGET = $$qtLibraryTarget($$TARGET)
    uri = QMLExtension

    DEFINES += QMLEXTENSION_LIBRARY

    SOURCES += CppClass.cpp
    QMLExtensionPlugin.cpp

    HEADERS += CppClass.hpp
    QMLExtensionPlugin.hpp

    OTHER_FILES +=
    qmldir

    !equals(PRO_FILE_PWD, $$OUT_PWD) {
    copy_qmldir.target = $$OUT_PWD/qmldir
    copy_qmldir.depends = $$PRO_FILE_PWD/qmldir
    copy_qmldir.commands = $(COPY_FILE) "$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)" "$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)"
    QMAKE_EXTRA_TARGETS += copy_qmldir
    PRE_TARGETDEPS += $$copy_qmldir.target
    }

    qmldir.files = qmldir
    unix {
    installPath = $$[QT_INSTALL_QML]/$$replace(uri, \., /)
    qmldir.path = $$installPath
    target.path = $$installPath
    INSTALLS += target qmldir
    }
    @

    CppClass.hpp:
    @#ifndef QMLEXTENSION_CPPCLASS_HPP
    #define QMLEXTENSION_CPPCLASS_HPP

    #include <QtCore/QObject>

    #include "QMLExtension_Global.h"

    namespace QMLExtension{

    class QMLEXTENSIONSHARED_EXPORT CppClass: public QObject {
    Q_OBJECT

    Q_DISABLE_COPY(CppClass)
    

    public:
    CppClass(QObject *parent = 0);
    ~CppClass();

    // Some more functions...
    

    };

    bool operator==(const CppClass &lclass, const CppClass &rclass);

    } // namespace QMLExtension

    #endif // QMLEXTENSION_CPPCLASS_HPP
    @

    QMLExtensionPlugin.hpp:
    @#ifndef QMLEXTENSIONPLUGIN_HPP
    #define QMLEXTENSIONPLUGIN_HPP

    #include <QtQml/QQmlExtensionPlugin>

    class QMLExtensionPlugin : public QQmlExtensionPlugin
    {
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")

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

    #endif // QMLEXTENSIONPLUGIN_HPP
    @

    QMLExtensionPlugin.cpp:
    @#include <qqml.h>

    #include "QMLExtensionPlugin.hpp"

    #include "CppClass.hpp"

    void QMLExtensionPlugin::registerTypes(const char *uri)
    {
    qmlRegisterTypeQMLExtension::CppClass(uri, 1, 0, "CppClass");
    }
    @

    And finally the qmldir-file:
    @module QMLExtension
    plugin QMLExtension
    classname QMLExtensionPlugin
    @

    In Window.qml i then want to import it like this:
    @import QMLExtension 1.0@

    When I now build everything and run the Application i get:
    @QQmlApplicationEngine failed to load component
    qrc:/qml/Window/Window.qml:5 module "QMLExtension" is not installed@

    This happens if i set my QML2_IMPORT_PATH to D:\Projects\Qt\QMLApplication\Build\QMLExtension\Desktop_Qt_5_2_0_MSVC2012_32bit\

    If I set it to D:\Projects\Qt\QMLApplication\ I get the following output:
    @QQmlImports(qrc:/qml/Window/Window.qml)::addLibraryImport: "QMLExtension" 1.0 as ""
    QQmlImports(qrc:/qml/Window/Window.qml)::importExtension: loaded "D:/Projects/Qt/QMLApplication/QMLExtension/qmldir"
    QQmlImportDatabase::resolvePlugin: Could not resolve plugin "QMLExtension" in "D:/Projects/Qt/QMLApplication/QMLExtension"
    QQmlApplicationEngine failed to load component
    qrc:/qml/Window/Window.qml:5 module "QMLExtension" plugin "QMLExtension" not found@

    So this time the qmldir file located in my project directory is recognized. Here I already wonder why the one in the Build directory was not recognized.
    If I would now copy the .dll from the build directory in the project diretory it start correctly.

    So can anybody explain why it only works the second way?
    Also if I copy the qmldir and .dll files directly to the executable it does not start...
    At least I don't want to copy the .dll for every start of the application...

    Regards


Log in to reply