Qt中两个插件的信号/插槽交互

时间:2012-01-24 20:07:07

标签: c++ qt plugins qt4

所以基本上我有一个小应用程序加载两个插件和connect它们。加载后的第一个插件会创建一个没有任何标题的标签,该标签将被添加到主窗口中。第二个插件创建一个将添加到菜单的操作。所以我的应用只需要加载这些插件并connect。连接它们的意思是什么?我的意思是标签插件包含一个将修改标签标题的插槽,动作插件会声明一个信号。应用程序应connect动作插件信号带标签插槽。我不知道该怎么做。我的猜测是动作插件类的实现是将自定义信号与标准信号(触发)连接起来。但无论如何这种方式我的应用程序不能像我预期的那样工作。如何在我的应用程序中为来自另一个插件的插件和插槽的信号进行正确连接?

这是我的标签插件代码:

#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)

动作插件:

    #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)

在我的应用中,我尝试加载插件,我有:

   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 个答案:

答案 0 :(得分:3)

您需要能够从每个插件访问QObject实例,以便在connect调用中使用它。我会为你的接口添加方法来做到这一点。我见过的一种模式是将接口转换为QObject指针的运算符,如:

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

意见可能会有所不同,不论是好风格,还是解决问题(如果您不喜欢运算符,请使用名为asQObject()的方法或类似方法。)