Signal/Slot interaction for two plugins in Qt

2019-02-17 11:35发布

问题:

So basically i have a little application that loads two plugins and connect them. First plugin after it's loaded it creates a label without any title which will be added to main window. Second plugin creates an action which will be added to a menu. So my app need just to load these plugins and to connect them . What i mean by connecting them ? i mean that label plugin contains a slot which will modify label's title , and action plugin has a signal declared. Application should connect action plugin signal with label slot. I do not know how to do it exactly. My guess is that in action plugin class implementation is to connect custom signal with a standart signal (triggered). But anyway this ways my app is not working as i expected. How can i make a correct connection in my app for a signal from one plugin and slot from another plugin ??

Here is my code for Label Plugin :

#include "LabelInterface.h"

class LabelPlugin : public LabelInterface {

    Q_OBJECT
    Q_INTERFACES(LabelInterface)

public:
    QLabel* label;
    QLabel* newLabel();
     LabelPlugin() {}
    ~LabelPlugin() {}

public slots:
    void setTextforLabel();
}; 

#include <QtGui>
#include "LabelPlugin.h"

QLabel* LabelPlugin::newLabel() {

    label = new QLabel("");
    return label;
}

void LabelPlugin::setTextforLabel() {

    label->setText("This plugin works fine");
}

// Exporta plugin-ul
Q_EXPORT_PLUGIN2 (labelplugin,LabelPlugin)

Action Plugin :

    #include "ActionInterface.h"

    class ActionPlugin : public ActionInterface  {

        Q_OBJECT
        Q_INTERFACES (ActionInterface)

    public :
         QAction* myAction;
         QAction* newAction();

        ~ActionPlugin () {}
         ActionPlugin () {}

    public slots:
         void send_signal();

     signals :
         void pushMyAction();
    };

#include <QtGui>
#include "ActionPlugin.h"

QAction* ActionPlugin::newAction() {

    myAction = new QAction("Show text",this);

    return myAction;
}

void ActionPlugin::send_signal() {

    qDebug ()<<"Here";

    QAction::connect (this,SIGNAL(pushMyAction()),this,SIGNAL(triggered()));
}

Q_EXPORT_PLUGIN2 (actionplugin,ActionPlugin)

In my app , where i try to load plugins i have :

   foreach (QString fileName, appDir.entryList(QDir::Files)) {

        qDebug()<<QString(fileName);

        QPluginLoader pluginLoader(appDir.absoluteFilePath(fileName));

        QObject* plugin = pluginLoader.instance();

         if (plugin) {

            ActionInterface* myAction= qobject_cast<ActionInterface*>(plugin);

            if (myAction) {
                action_ = myAction;
                pluginMenu->addAction(action_->newAction());
            }

            LabelInterface* myLabel = qobject_cast<LabelInterface*>(plugin);

            if (myLabel) {
                label_=myLabel;
                layout->addWidget(label_->newLabel());
            }

            if (action_ && label_) {

                qDebug()<<"both loaded";

                action_->send_signal();
                connect(action_, SIGNAL(pushMyAction()),label_, SLOT(setTextforLabel()));
            }
            else qDebug() << "seems one plugin is not loaded";
        }
    }

回答1:

You need to be able to access a QObject instance from each plugin so you can use it in the connect call. I would add methods to your interfaces to do this. One pattern I've seen is an operator to convert the interface to a QObject pointer, like:

class MyInterface {
public:
    virtual operator QObject*() = 0;
};

Opinions may vary on whether that's good style, but it solves the problem (if you don't like the operator, use a method called asQObject() or similar).



标签: c++ qt plugins qt4