Qmake rules for C++ plugin extension to QML



  • Hi all,

    I am struggling with the necessary qmake magic to make use of a C++ plugin I built for QML. (On Windows)

    My project is just an at-home learning adventure where I download my Strava cycling activities and try to do some interesting statistical analysis on them. That all works fine.

    The project is laid out as follows:

    0_1472341760487_projectLayout.PNG

    I.e. 3 subdirs... 'cppSrc' is the main plugin, 'main' is my test app, where I want to use the plugin in QML, and 'UnitTests' is obvious.

    The 'DeepStats.pro' file looks like this:
    TEMPLATE = subdirs

    SUBDIRS +=
    main
    UnitTests
    cppSrc

    main.depends = cppSrc
    UnitTests.depends = cppSrc

    The 'cppSrc.pro' file looks like this:
    QT -= gui
    QT += core network qml
    CONFIG += qt shared plugin

    ! include(../common.pri) {
    error("Couldn't find the common.pri file")
    }

    TARGET = deepstats
    TEMPLATE = lib

    DEFINES += DEEPSTATS_LIBRARY

    SOURCES +=
    stravaaccess.cpp
    stravastats.cpp
    stravaactivities.cpp
    stravaactivity.cpp
    stravarangesummary.cpp
    stravaactivitiesmodel.cpp
    stravaportal.cpp

    HEADERS +=
    deepstats_global.h
    stravaaccess.h
    stravastats.h
    stravaactivities.h
    stravaactivity.h
    stravarangesummary.h
    stravaactivitiesmodel.h
    stravaportal.h
    deepstats_plugin.h

    unix {
    target.path = /usr/lib
    INSTALLS += target
    }

    The 'main.pro' file looks like this:
    QT += qml quick

    CONFIG += c++11

    ! include(../common.pri) {
    error("Couldn't find the common.pri file")
    }

    SOURCES += main.cpp

    INCLUDEPATH += ../cppSrc

    RESOURCES += qml.qrc

    QML_IMPORT_PATH = .

    include(deployment.pri)

    QMAKE_RPATHDIR += $$DESTDIR

    LIBS += -L$$DESTDIR -ldeepstats

    My 'deepstats_plugin.h' file looks like this:
    #ifndef DEEPSTATS_PLUGIN_H
    #define DEEPSTATS_PLUGIN_H

    #include <QtQml>
    #include <QQmlExtensionPlugin>
    #include "stravaportal.h"
    #include "stravaactivitiesmodel.h"

    class DeepStats_Plugin : public QQmlExtensionPlugin
    {
    Q_OBJECT
    Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
    public:
    void registerTypes(const char *uri)
    {
    Q_ASSERT(uri == QLatin1String("ca.scumpyware.deepstats"));
    qmlRegisterType<StravaPortal>(uri, 1, 0, "StravaPortal");
    qmlRegisterUncreatableType<StravaActivitiesModel>(uri, 1, 0, "StravaActivitiesModel",
    "StravaActivitiesModel is uncreatable");
    }
    };

    #endif // DEEPSTATS_PLUGIN_H

    my 'qmldir' file (in cppSrc), looks like this:
    module ca.scumpyware.deepstats
    plugin deepstats

    So, if I add 'import ca.scumpyware.deepstats 1.0' to my main.qml file, I get the following error:

    QQmlApplicationEngine failed to load component
    qrc:/main.qml:5 module "ca.scumpyware.deepstats" is not installed

    Can somebody please explain what I need to install, and where, and how to make the qmake/*.pro file changes to accomplish this???

    Thanks in advance...



  • Hi... I got this to work by adding this to my cppSrc.pro file:
    win32 {
    # The dir I want the plugin installed to...
    WAYNES_PLUGIN_DIR = C:\Users\wayne_000\Documents\QtProjects\WaynesPlugins\ca\scumpyware\deepstats
    ##message($$WAYNES_PLUGIN_DIR)

    # If my dir doesn't exist, create it...
    PLUGIN_INSTALL_DIR = $$WAYNES_PLUGIN_DIR
    if (!exists($$PLUGIN_INSTALL_DIR)) {
        message("CREATING DIR")
        createpluginsdir.commands = $(MKDIR) $$PLUGIN_INSTALL_DIR
    
        QMAKE_EXTRA_TARGETS += createpluginsdir
        PRE_TARGETDEPS += createpluginsdir
    }
    else {
        message("NOT CREATING DIR")
    }
    
    
    # Now, copy the lib's & the qmldir file to the plugin install dir...
    EXTRA_BINFILES += \
        $$DESTDIR/*.dll \
        $$DESTDIR/*.lib \
        $$DESTDIR/*.pdb \
        $$PWD/qmldir
    EXTRA_BINFILES_WIN = $${EXTRA_BINFILES}
    EXTRA_BINFILES_WIN ~= s,/,\\,g
        DESTDIR_WIN = $${PLUGIN_INSTALL_DIR}
    DESTDIR_WIN ~= s,/,\\,g
    for(FILE,EXTRA_BINFILES_WIN){
                QMAKE_POST_LINK +=$$quote(cmd /c copy /y $${FILE} $${DESTDIR_WIN}$$escape_expand(\n\t))
    }
    

    }

    Then, I added the following to my main.cpp file:

    // ******************************************************************************
    // Add the import path to my plugins...
    QStringList importPathList = engine.importPathList();
    importPathList.append("C:/Users/wayne_000/Documents/QtProjects/WaynesPlugins");
    engine.setImportPathList(importPathList);
    qDebug() << "Path List: " << engine.importPathList();
    // ******************************************************************************
    

    My logic to only create my output plugin directory if it doesn't already exist doesn't seem to work all the time, but if you delete it manually, it all works. Kludgey, I know, but this has been quite frustrating. Surely there is an easier way!!!!


Log in to reply
 

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