Create a plugins



  • i create 2 projects. in the first project i create few objects(declerativeItems) and used the qmlRegisterType to create the connection to qml.
    now i would like to use this objects in the second project, without to include the files in the pro file.....
    how can i do that correctly?
    i tried to use the CONFIG += ... but this does not work.



  • Use INCLUDEPATH, LIBS and make sure your first program exports all the necessary objects you want to use in your second plugin (like you would if you were building a shared library).
    That means in your first program you have to have something like:
    .pro
    @
    DEFINES += MY_LIBRARY
    @
    global.h
    @
    #include <QtCore/qglobal.h>

    #if defined(MY_LIBRARY)

    define MYSHARED_EXPORT Q_DECL_EXPORT

    #else

    define MYSHARED_EXPORT Q_DECL_IMPORT

    #endif
    @
    And your classes with
    @
    class MYSHARED_EXPORT class1
    @

    And you should adjust the defines (MY_LIBRARY, MYSHARED_EXPORT) to fit your plugin, they should be different for every lib you do.



  • This "article":http://developer.qt.nokia.com/doc/qt-4.7/qml-extending-tutorial-index.html explains how to extend QML using C++ and in particular section 6 shows you how to make your custom QDeclarative items into a reusable plugin.



  • in the second project- when i want to use the objects from the first project in qml file , i got this error: module "Operands" is not installed - for the line : import Operands 1.0
    i created an object OperandItem in the 1st project, and write :
    qmlRegisterType<OperandItem> ("Operands", 1, 0, "MYOperand");

    and i am trying to use this from the qml in the 2nd project... in the qml the MYOperand is known, but i got this error .



  • Did you follow the steps in the docs? ie have you actually made a plugin (a shared lib that can be loaded by your 2nd project)?



    1. in the 1st project i write :

    @
    #if defined(MY_NGWIDGETS_LIBRARY)

    define MYSHARED_EXPORT Q_DECL_EXPORT

    #else

    define MYSHARED_EXPORT Q_DECL_IMPORT

    #endif

    class MYSHARED_EXPORT MyClass{...}
    @

    for each class that i want to use in the 2nd project.

    2.in the pro file (of the 1st project) i write:
    @
    TARGET = NGWidgets
    TEMPLATE = app
    DEFINES += MY_NGWIDGETS_LIBRARY
    CONFIG += qt plugin
    DESTDIR = app
    OBJECTS_DIR = tmp
    MOC_DIR = tmp
    @

    1. i also create a qmldir file and write:

    @
    plugin NGWidgets-plugins app
    @

    then i tried to use the plugin from the 2nd project.
    but it still say that the modules are not installed

    Edit: Please use @ tags to delimit blocks of code etc.



  • Well for a start the 1st project needs to have
    @
    TEMPLATE = lib
    @
    rather than "app" since you are trying to make a plugin which is a shared library.



  • now i got this error:
    The process could not be started: The system cannot find the file specified. - for the line:
    @DESTDIR = lib



  • What process? Can you post your 2 projects please? Either that or be alot more descriptive in what you are doing. You are not giving us enough information to understand what the problem is.

    You will not be able to execute your 1st project since that will just be a plugin library not an application.



  • 1st project:

    operanditem.h

    @ #if defined(MY_NGWIDGETS_LIBRARY)

    define MYSHARED_EXPORT Q_DECL_EXPORT

    #else

    define MYSHARED_EXPORT Q_DECL_IMPORT

    #endif

    class MYSHARED_EXPORT OperandItem : public QObject
    {.....}@

    main.c

    @qmlRegisterType<OperandItem> (“Operands”, 1, 0, “MYOperand”);@

    pro file

    @QT += core gui
    QT += declarative
    QT += network
    QT += xml

    TARGET = NGWidgets
    TEMPLATE = lib
    DEFINES += MY_NGWIDGETS_LIBRARY
    CONFIG += qt plugin
    DESTDIR = lib
    OBJECTS_DIR = tmp
    MOC_DIR = tmp

    SOURCES +=
    main.cpp \
    Operands/operanditem.cpp
    HEADERS +=
    Operands/operanditem.h

    @

    2nd project:

    in some qml file i write:

    @ import QtQuick 1.0
    import Operands 1.0

    Rectangle{
    MYOperand{}
    }@



  • You better append your second .pro file too.



  • Please have another read through this "article":http://developer.qt.nokia.com/doc/qt-4.7/declarative-tutorials-extending-chapter6-plugins.html#id-8c522ec4-43c2-4344-a4a4-148efcc18b7d and you'll see that you also need to write a plugin class derived from QDeclarativeExtensionPlugin that your 2nd project's QML engine will call the registerTypes() function of in order to register them with your 2nd project.

    This plugin class seems to be completely missing from you 1st project.



  • i have this class inherit from QDeclarativeExtensionPlugin and create the plugin.
    i don't know what i need to add to the 2nd project (in the pro file) to make it work with the new module...



  • You need to edit the qmldir file in your 2nd project so that it points at the path where the plugin library from your 1st project is located.



  • the dll file was created in the build-desktop directory(in the debug) and not in the QtCreator\lib\ directory... even when i copy the dll to this place it does not work



  • in the pro file i write:

    @QTPLUGIN += NGWidgets
    LIBS += -L"C:/Qt/Projects/NGWidgets-build-desktop/debug"
    LIBS += -lNGWidgets@

    in the folder "C:/Qt/Projects/NGWidgets-build-desktop/debug"
    i have the dll (NGWidgets.dll)

    but i got the error:
    :-1: error: cannot find -lngwidgetsd
    collect2: ld returned 1 exit status



  • I don't think that your 2nd project's .pro file needs to mention the NGWidgets plugin lib at all. The qmldir file tells the QDeclarativeEngine where it can dllopen your plugin library from.

    Also the error message you posted does not match the .pro file you have posted the error message is referring to ngwidgetsd.dll whereas the .pro file mentions NGWidgets.dll (not the trailing d).

    In your 1st project (the plugin one) make sure you are using the Q_EXPORT_PLUGIN2 macro as is mentioned in the docs:

    @
    Q_EXPORT_PLUGIN2( NGWidgets, NGWidgetsPlugin )
    @

    where I have assumed that your plugin class (the one derived from QDeclarativeExtensionPlugin) is called NGWidgetsPlugin (since you have not shown it to us).

    Try using a qmldir file for your 2d project that looks like this:

    @
    plugin NGWidgets C:/Qt/Projects/NGWidgets-build-desktop/debug
    @

    and in your .qml file using

    @
    import NGWidgets 1.0
    @



  • that exaclly what i did - and i create alse qmldir file in the first project (as shown in the example)....

    in this link : http://doc.qt.nokia.com/latest/plugins-howto.html
    they say that the pro file of the 2nd project should be changed...



  • I do not see anything in that document relating to qml plugins. Rather than this constant back and forth can you provide a zip file of your two projects that we can try to fix up for you please?



  • i can't post all my code. but this is the main classes:

    1st project :

    ngwidgetsplugin.h

    @#include <QDeclarativeExtensionPlugin>

    class NGWidgetsPlugin: public QDeclarativeExtensionPlugin
    {
    Q_OBJECT
    public:
    void registerTypes(const char *uri);
    };@

    ngwidgetsplugin.cpp

    @#include <QtDeclarative>
    #include <QtPlugin>
    //.....more includes for files

    void NGWidgetsPlugin::registerTypes(const char *uri)
    {
    qmlRegisterType<OperandItem> (uri, 1, 0, "MYOperand");

       //................. 
    

    }

    Q_EXPORT_PLUGIN2(NGWidgets, NGWidgetsPlugin)@

    .pro

    @QT += core gui
    QT += declarative
    QT += network

    #TARGET = NGWidgets
    TEMPLATE = lib
    CONFIG += qt plugin
    DESTDIR = lib
    OBJECTS_DIR = tmp
    MOC_DIR = tmp

    SOURCES += ...
    HEADERS += ...
    OTHER_FILES += ...
    @

    qmldir

    @plugin NGWidgets lib@

    2nd project - use the plugin

    .pro

    @QT += core gui
    QT += declarative
    QT += network

    SOURCES += ...
    HEADERS += ...
    OTHER_FILES += ...@

    qmldir

    @plugin NGWidgets C:/Qt/Projects/NGWidgets-build-desktop/debug @

    app.qml

    @import QtQuick 1.0
    import NGWidgets 1.0

    Rectangle
    {
    MYOperand{...}
    }

    @

    i got the error : module "NGWidgets" is not installed
    for line 2



  • Be also aware that you usually cannot mix release and debug code.



  • so how can i connect to the plugin, that locate in the debug dir?



  • I just wanted to point out that if you compile your application in debug mode you should compile your plugins in debug mode too (same goes for release builds).

    However - have you tried to "trace the module import":http://developer.qt.nokia.com/doc/qt-4.7/qdeclarativedebugging.html?

    EDIT: Are you sure that path in your qmldir file is correct? You instruct qmake to place your library in a "lib" directory but your path points to the "debug" directory. -As far as I have understood the documentation you do not need both - the qmldir and the import statement. You can omit one.-



  • yes, i give the path to the location of NGWidgets.dll , and this dll is locate in the debug dir of the plugin project and also in the lib directory (in 2 cases it's not recognize the "module")...



  • The .dll in your debug directory is most likely an outdated version, as all new versions are moved to the lib directory (as specified as DESTDIR in the .pro file). You are pointing to the wrong directory in your qmldir file.

    Have you already tried tracing the module import?



  • ok - you right , i changed it to :
    @plugin NGWidgets C:/Qt/Projects/NGWidgets-build-desktop/lib@
    but still have the same problem



  • Have you already tried tracing the module import?



  • this is the output:
    QDeclarativeImportDatabase::addImportPath: "C:\QtSDK\Desktop\Qt\4.7.3\mingw\imports"
    QDeclarativeImportDatabase::addImportPath: "C:/Qt/Projects/App-build-desktop/debug"
    QDeclarativeImports(C:/Qt/Projects/App/app.qml)::addImport: "." -1.-1 File as ""
    QDeclarativeImports(C:/Qt/Projects/App/app.qml)::addImport: "QtQuick" 1.0 Library as ""
    QDeclarativeImports(C:/Qt/Projects/App/app.qml)::addImport: "NGWidgets" 1.0 Library as ""
    C:/Qt/Projects/App/app.qml:3:1: module "NGWidgets" is not installed



  • is this a good output?





  • yes, this is in the main directory of the App project...



  • the dll islocate in the "C:\Qt\Projects\NGWidgets-build-desktop\lib"
    and the qmldir file is in "C:\Qt\Projects\App"



  • can someone post please code of 2 project (one plugin, and one qml application that use the plugin) , when the projects are not under the same build , and it work for him please.



  • Yup only takes 10 minutes! You can find the projects at:

    "Project 1 (the QML plugin)":http://www.theharmers.co.uk/busyindicator.tar.gz
    "Project 2 (the app using the plugin)":http://www.theharmers.co.uk/simpleqmlapp.tar.gz

    You will need to alter the following things to make it work on your system:

    In busyindicator.pro edit the line

    @
    target.path = $$(HOME)/local/lib
    @
    to a path of your choice.

    In the 2nd project edit the file simpleqmlapp/qml/simpleqmlapp/qmldir so that the path matches what you set in the .pro file above. By default it contains:

    @
    plugin zapbsqmlplugin /home/sean_harmer/local/lib
    @

    With the above mods in place, just do:

    @
    qmake
    make
    make install
    @

    in the busyindicator project. Followed by:

    @
    qmake
    make
    @

    in the simpleqmlapp project.



  • thank you for all your help. i will check this example :)


Log in to reply
 

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