[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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.