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

QTplugin for beginner



  • I am new in qTplugin.i dont know how to startup.i have followed https://doc-snapshots.qt.io/qtcreator-extending/first-plugin.html But i am getting error :
    mypluginplugin.h:5: error: extensionsystem/iplugin.h: No such file or directory

    What are extensionsystem & iplugin and how can i add it on my file.


  • Lifetime Qt Champion

    Hi,

    Might be a silly question but what kind of plugin do you want to build ? For Qt Creator or for your application ?



  • @SGaist for my application.
    I read QT document about pugins but I'm not able to understand where to start, and how to add iplugin and extensionsystem.
    what type of project should I use , meaning from the scratch...NewProject->...?


  • Lifetime Qt Champion

    Then you are following the wrong guide. That's for Qt Creator plugins.

    Following this part of the documentation and the linked examples.



  • @SGaist ohh thanks.i will go through it.



  • @SGaist hey what is the difference between GUI and plugin.


  • Lifetime Qt Champion

    GUI: Graphical User Interface

    Plugin: add-on that implements features for an application/library without requiring to rebuild said library/application.



  • @SGaist thank you
    So it mean if I have an application, lets say app-1 and I want to use app-2 in app-1 , so I need to create plugin of app-2 and add it to app-1?


  • Lifetime Qt Champion

    @JadeN001 said in QTplugin for beginner:

    @SGaist thank you
    So it mean if I have an application, lets say app-1 and I want to use app-2 in app-1 , so I need to create plugin of app-2 and add it to app-1?

    Yes, that should work.


  • Lifetime Qt Champion

    @JadeN001
    Normally the story would be more like
    App 1 has some features that App 2 could also use.
    Then you take the features and put in plugin.
    Now both apps can use the same code via the plugin.

    Other use cases is that some features are not used all the time. So
    putting them in a plugin, allows the app to start faster and first load the extra features when needed.

    Other use case is some sort of base App. user can then get extra features via plugins.
    Often the plugins could be made by other people than the programmer of the main app.

    So its both a system for dividing the code to smaller blocks as not to have one BIG fat App.

    Its also a way to allow external people to add features to your app , or allow you to have a base app and more features can be had via plugins. ( to make app extensible without having the source code )



  • I am trying to create a plugin of widget.
    for that i have created 2 sub-projects. one is of widgets and second is of plugin. but i am not able to include header file of widget in to plugin.
    so,how to include files into another project.

    main project pro:
    TEMPLATE = subdirs

    SUBDIRS +=
    pluginwidgets
    plugin

    I



  • Here another issue i'm facing ,I don't know exact reason behind it .
    Getting error of :

    ```'server_task' does not name a type
         server_task* m_server;
         ^
    
    mainwindow.h file :
    
    
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include<QWidget>
    #include"server_task.h"
    #include"broadcastmsg.h"
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
        void addmessage(QString msg);
    private slots:
        void on_pushButton_Start_clicked();
    
        void on_actionSendToAll_triggered();
    
    private:
        Ui::MainWindow *ui;
        BroadCastmsg *b;
        server_task* m_server;
    
    };
    
    #endif // MAINWINDOW_H
    
    


  • okay,my problem is solved.i have to just declare class name
    class server_task before
    class maiwindow
    {
    }

    class server_task;    //  <------here
    class MainWindow : public QMainWindow
    {....
    .....
    }
    

    But i don't know why it is required because i have already include header file of it.


  • Lifetime Qt Champion

    Hi
    To declare
    server_task* m_server;

    it needs to have seen type/class server_task
    either via
    class server_task; // forwarding
    or
    #include "server_task.h"



  • @mrjj It means that only including header file "server_task.h" it should work.if so,it does not work in my case.I have to add :

    class server_task;
    


  •  Error: Plugin Metadata file "broadcastplugin.json" does not exist. Declaration will be ignored
    
    plugin.h
    
    #ifndef BROADCAST_PLUGIN_H
    #define BROADCAST_PLUGIN_H
    #include<QObject>
    #include<QString>
    #include"C:\Users\Kits\Documents\ServerWithPlugin\Server/interface_broadcast.h"
    class broadcast_Plugin:public QObject,interface_broadcast
    {
        Q_OBJECT
        Q_PLUGIN_METADATA(IID "org.qt-project.Qt.BroadcastInterface" FILE "broadcastplugin.json")
        Q_INTERFACES(interface_broadcast)
    
    public:
        broadcast_Plugin();
        void sendmsg(QString msg) override;
    signals:
        void sendToALL(QString m);
    
    };
    
    #endif // BROADCAST_PLUGIN
    
    plugin.pro file:
    #! [0]
    TEMPLATE        = lib
    CONFIG         += plugin
    QT             += widgets
    INCLUDEPATH    += ../echowindow
    HEADERS         = echoplugin.h
    SOURCES         = echoplugin.cpp
    TARGET          = $$qtLibraryTarget(echoplugin)
    DESTDIR         = ../plugins
    #! [0]
    
    EXAMPLE_FILES = broadcastplugin.json
    
    # install
    target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin/plugins
    INSTALLS += target
    
    CONFIG += install_ok  # Do not cargo-cult this!
    
    

  • Lifetime Qt Champion

    @JadeN001

    well its never needed with both. ever :)
    so something else.

    regarding:
    broadcastplugin.json
    you have to make it yourself.



  • @mrjj I am new in this area,so can u guide me how to create a .json file!



  • I am really stuck in plugin.Can anyone suggest me the basic video/guideline of how to start with plugin for application. As based on qt documentation "echo-plugin" example
    http://doc.qt.io/qt-5/qtwidgets-tools-echoplugin-example.html.
    As a main project, which type of project should be chosen.how to create .json file for echo plugin(from QT Examples) which type of project I should choose. I am not getting clear idea from qt documentation.
    Currently I am using "empty Qmake project " for echoplugin .


  • Lifetime Qt Champion

    @JadeN001
    Just create the .json file
    echoplugin.json
    only contains {} ( empty json object ) and
    that prevents the warning.

    You can use any template for plugin but "empty Qmake project " should be fine, but make sure you
    add the needed stuff in .pro
    most critical being
    TEMPLATE = lib
    CONFIG += plugin

    There is also the old sample
    https://doc.qt.io/archives/qt-5.10/qtwidgets-tools-plugandpaint-plugins-basictools-example.html
    That shows a paint program that uses plugins to add brushes and pens. Not sure why its retired.

    why not copy echo sample and just change names ?
    Most plugin code is the same for all plugins.
    The only part that differ is names and and the actual feature code of the plugin. (what it does)



  • @mrjj yeah,thank you very much...I will go through as u have guided.



  • plugin.pro: 
    
    TEMPLATE        = lib
    CONFIG         += plugin release
    
    QT             += widgets
    INCLUDEPATH    += "C:\Users\Kits\Documents\testplugin\test\mainwindow"
    HEADERS += \
        testit.h \
        interface.h
    
    SOURCES += \
        testit.cpp
    TARGET          = $$qtLibraryTarget(testplugin)
    EXAMPLE_FILES = PluginS.json
    
    DISTFILES += \
        PluginS.json
    
    mainwindow.pro:
    
    QT       += core gui
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = testit
    TEMPLATE = app
    CONFIG = release
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which has been marked as deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    
    SOURCES += \
            main.cpp \
            mainwindow.cpp
    
    HEADERS += \
            mainwindow.h \
        interface.h
    
    FORMS += \
            mainwindow.ui
    
    QMAKE_PROJECT_NAME = mainwindow
    win32 {
        CONFIG(debug, release|debug):DESTDIR = ../debug/
        CONFIG(release, release|debug):DESTDIR = ../release/
    } else {
        DESTDIR    = ../
    }
    
    mainwindow.cpp:
    
    
    pluginsDir.cd("plugins");
        foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
            QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
            QObject *plugin = pluginLoader.instance();
            qDebug()<<plugin;
    

    I am getting plugin value as a QObject(0x0).I think plugin is not getting loaded.


  • Lifetime Qt Champion

    Hi
    you do something like sample ?

    bool EchoWindow::loadPlugin()
    {
        QDir pluginsDir(qApp->applicationDirPath());
    #if defined(Q_OS_WIN)
        if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
            pluginsDir.cdUp();
    #elif defined(Q_OS_MAC)
        if (pluginsDir.dirName() == "MacOS") {
            pluginsDir.cdUp();
            pluginsDir.cdUp();
            pluginsDir.cdUp();
        }
    #endif
        pluginsDir.cd("plugins");
        foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
            QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
            QObject *plugin = pluginLoader.instance();
            if (plugin) {
                echoInterface = qobject_cast<EchoInterface *>(plugin);
                if (echoInterface)
                    return true;
            }
        }
    
        return false;
    }
    

    you should output
    http://doc.qt.io/qt-5/qpluginloader.html#errorString

    and see if it gives a hint



  • @mrjj
    here i am getting error of:

    "Failed to extract plugin meta data from 'C:/Users/Kits/Documents/build-ServerWithPlugin-Desktop_Qt_5_10_1_MSVC2017_64bit-Release/Server/.qmake.stash'"
    QObject(0x0)
    
    "Failed to extract plugin meta data from 'C:/Users/Kits/Documents/build-ServerWithPlugin-Desktop_Qt_5_10_1_MSVC2017_64bit-Release/Server/Makefile'"
    QObject(0x0)
    outside if
    "Failed to extract plugin meta data from 'C:/Users/Kits/Documents/build-ServerWithPlugin-Desktop_Qt_5_10_1_MSVC2017_64bit-Release/Server/Makefile.Debug'"
    QObject(0x0)
    
    "Failed to extract plugin meta data from 'C:/Users/Kits/Documents/build-ServerWithPlugin-Desktop_Qt_5_10_1_MSVC2017_64bit-Release/Server/Makefile.Release'"
    QObject(0x0)
    "Failed to extract plugin meta data from 'C:/Users/Kits/Documents/build-ServerWithPlugin-Desktop_Qt_5_10_1_MSVC2017_64bit-Release/Server/ui_broadcastmsg.h'"
    QObject(0x0)
    "Failed to extract plugin meta data from 'C:/Users/Kits/Documents/build-ServerWithPlugin-Desktop_Qt_5_10_1_MSVC2017_64bit-Release/Server/ui_mainwindow.h'"
    

  • Lifetime Qt Champion

    is that what errorString gives ?



  • @mrjj yes


  • Lifetime Qt Champion

    @JadeN001

    Sorry. no idea. Google gives nothing.

    Check against the sample.
    Must be some difference since that works.



  • @mrjj okay thanks



  • Might be silly question but I am stuck with it from very long at this point.

    interface.h

    #ifndef ECHOINTERFACE_H
    #define ECHOINTERFACE_H
    #include<QString>
    class EchoInterface
    {
    public:
        virtual ~EchoInterface() {}
        virtual QString echo(const QString &message) = 0;
    };
    
    
    QT_BEGIN_NAMESPACE
    
    #define EchoInterface_iid "org.qt-project.Qt.Examples.EchoInterface"
    
    Q_DECLARE_INTERFACE(EchoInterface, EchoInterface_iid)
    
    QT_END_NAMESPACE
    
    #endif // ECHOINTERFACE_H
    
    

    plugin_msg.h

    #ifndef PLUGIN_MSG_H
    #define PLUGIN_MSG_H
    #include"echointerface.h"
    #include<QObject>
    class plugin_msg:public QObject,EchoInterface
    {
    
        Q_OBJECT
        Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.EchoInterface" )
        Q_INTERFACES(EchoInterface)
    
    public:
        QString echo(const QString &message);
        plugin_msg();
    };
    
    #endif // PLUGIN_MSG_H
    
    

    error:

     error: C2259: 'EchoInterface': cannot instantiate abstract class
     due to following members:
     'QString EchoInterface::echo(const QString &)': is abstract
    : see declaration of 'EchoInterface::echo'
    : C2059: syntax error:'string'//Q_DECLARE_INTERFACE(EchoInterface,EchoInterface_iid)
    
    : 'QObject' should be preceded by ';' // in qobjectdef_imp.h file
    

    what is wrong?


  • Lifetime Qt Champion

    Hi
    EchoInterface::echo is pure virtual.
    That is indicated with the =0 in end of line
    virtual QString echo(const QString &message) = 0;

    That means your subclass MUSt implement it.

    do you have
    plugin_msg:: echo(const QString &message) {
    ...
    }

    in the .cpp for plugin_msg?



  • @mrjj yes


  • Lifetime Qt Champion

    Hi,

    There's no sign of declaration nor implementation of the echo method in the code you posted from your plugin_msg class.



  • @SGaist
    plugin_msg.h

    #ifndef PLUGIN_MSG_H
    #define PLUGIN_MSG_H
    #include"echointerface.h"
    #include<QObject>
    class plugin_msg:public QObject,EchoInterface
    {
    
        Q_OBJECT
        Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.EchoInterface" )
        Q_INTERFACES(EchoInterface)
    
    public:
        QString echo(const QString &message);
        plugin_msg();
    };
    
    #endif // PLUGIN_MSG_H
    

    plugin_msg.cpp

    #include "pluginmsg.h"
    
    #include "plugin_msg.h"
    
    plugin_msg::plugin_msg()
    {
    
    }
    QString plugin_msg::echo(const QString &message)
    {
        return message;
    }
    
    


  • @SGaist @mrjj hey thanks.my problem of interface is solved by just adding #include<QObject> before all the includes file in plugin_msg.h

    now again I'm getting the same old problem of' Can not load plugins'.

    "Failed to extract plugin meta data from 'C:/Users/Kits/Documents/build-plug_testit-Desktop_Qt_5_10_1_MSVC2017_64bit-Release/testitgui/Makefile'"
    "Failed to extract plugin meta data from 'C:/Users/Kits/Documents/build-plug_testit-Desktop_Qt_5_10_1_MSVC2017_64bit-Release/testitgui/Makefile.Debug'"
    "Failed to extract plugin meta data from 'C:/Users/Kits/Documents/build-plug_testit-Desktop_Qt_5_10_1_MSVC2017_64bit-Release/testitgui/Makefile.Release'"
    "Failed to extract plugin meta data from 'C:/Users/Kits/Documents/build-plug_testit-Desktop_Qt_5_10_1_MSVC2017_64bit-Release/testitgui/ui_mainwindow.h'"
    

  • Lifetime Qt Champion

    @JadeN001

    and you are 100% sure it actually find the plugin dll file ?

    please show how you load it.



  • @mrjj
    mainwindow.cpp

    #include<QPluginLoader>
    bool MainWindow::loadplugin()
    {   qDebug()<< qApp->applicationName();
        pluginsDir = QDir(qApp->applicationDirPath());
            qDebug()<<pluginsDir;
       #if defined(Q_OS_WIN)
           if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
               pluginsDir.cdUp();
       #elif defined(Q_OS_MAC)
           if (pluginsDir.dirName() == "MacOS") {
               pluginsDir.cdUp();
               pluginsDir.cdUp();
               pluginsDir.cdUp();
           }
       #endif
           qDebug()<<"here.."<< pluginsDir.cd("plugins");
           foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
               QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
               QObject *plugin = pluginLoader.instance();
             qDebug()<< pluginLoader.errorString();
               if (plugin) {
                   i = qobject_cast<interface *>(plugin);
                   if (i)
                       return true;
               }
           }
    
           return false;
    }
    

    In analysis i found that
    qDebug()<<"here.."<< pluginsDir.cd("plugins");
    returns false.
    but i don't know whether it creates "plugins" folder or it looks for the "plugins" folder already created or
    Is it related to the DESTDIR in plugin.pro file.because in QT examples it automatically creates a folder named plugins in the build folder of the project, which isn't happening in my case.
    plugin_msg.pro

    TARGET =plugin_msg
    TEMPLATE        = lib
    CONFIG         += plugin
    QT             += widgets
    INCLUDEPATH    +="C:\Users\Kits\Documents\plugin_task\GUI_msg"
    HEADERS += \
        plugin.h
    
    SOURCES += \
        plugin.cpp
    TARGET          = $$qtLibraryTarget(pnp_plugin)
    DESTDIR         = "C:\Users\Kits\Documents\plugin_task\plugins"
    
    DISTFILES += \
        Echoplugin.json
    
    

  • Lifetime Qt Champion

    The loader you use , looks for the plugins in a folder next to .exe
    and tried to go up and down depending on release and build.
    and then tries to enter plugins.

    So check you do in fact have that folder in that location and it has the DLL file.

    Alternatively, just load it directly with absolute path for test.



  • @mrjj thanks a lot for your answer and for the link https://suppsforlife.to/category/pct/
    also wanted to say thanks to everyone for all your answers as they were super helpful for me, as a beginner. was wondering if i may talk with your privately guys? or I should start a thread?


  • Lifetime Qt Champion

    @Offied
    Hi ( JadeN001 in office ?)
    Please make posts versus asking chat.
    Chat is bad for viewing code and nobody else can
    see the questions / answers or help with info so
    forum posts are always the best and help all the most.
    I assume by privately you mean in chat and not something else:)


  • Lifetime Qt Champion

    By the way, did you try adding the .json file with the plugin metadata to your project ?


Log in to reply