【问题标题】:Signal/Slot interaction for two plugins in QtQt中两个插件的信号/槽交互
【发布时间】:2012-02-18 02:01:18
【问题描述】:

所以基本上我有一个加载两个插件和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";
        }
    }

【问题讨论】:

  • 这可能根本不会有任何区别,但也许可以试试label_-&gt;connect(_action, SIGNAL(pushMyAction()));
  • 控制台输出没有任何连接错误吗?
  • 由于 Qt5 Q_EXPORT_PLUGIN2 已被弃用。

标签: c++ qt plugins qt4


【解决方案1】:

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

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

对于这是否是好的样式可能会有不同的看法,但它解决了问题(如果您不喜欢该运算符,请使用名为 asQObject() 或类似的方法)。

【讨论】:

  • 顺便说一句,我遇到了同样的问题。有时你想qobject_cast你的插件,总是需要先将它们转换为QObject,这会很烦人。
  • QPluginLoader::instance 将它们作为 QObjects 返回,我不明白您为什么需要将它们转换回 QObject?
  • 因为一般情况下你会 qobject_casting 到你的接口并使用它,并且没有办法将它转换回 QObject。你当然可以在任何地方传递 QObject* 和 MyInterface* ,但这也很尴尬。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-07
  • 2012-09-11
  • 2020-10-01
相关资源
最近更新 更多