Взаимодействие сигнал / слот для двух плагинов в Qt - PullRequest
6 голосов
/ 25 января 2012

Так что в основном у меня есть небольшое приложение, которое загружает два плагина и connect их. Первый плагин после загрузки создает ярлык без заголовка, который будет добавлен в главное окно. Второй плагин создает действие, которое будет добавлено в меню. Поэтому моему приложению нужно просто загрузить эти плагины и connect их. Что я имею в виду, соединяя их? я имею в виду, что плагин метки содержит слот, который будет изменять заголовок метки, а плагин действия имеет объявленный сигнал. Приложение должно connect сигнализировать плагин действия со слотом для метки. Я не знаю, как это сделать точно. Я предполагаю, что в действии реализация класса плагина заключается в соединении пользовательского сигнала со стандартным сигналом (сработавшим). Но так или иначе, мое приложение не работает так, как я ожидал. Как я могу сделать правильное соединение в моем приложении для сигнала от одного плагина и слот от другого плагина ??

Вот мой код для плагина Label:

#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 Ответ

3 голосов
/ 25 января 2012

Вы должны иметь возможность доступа к экземпляру QObject из каждого плагина, чтобы вы могли использовать его при вызове подключения. Я бы добавил методы к вашим интерфейсам, чтобы сделать это. Один шаблон, который я видел, - это оператор для преобразования интерфейса в указатель QObject, например:

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

Мнения могут различаться в зависимости от того, хороший ли это стиль, но это решает проблему (если вам не нравится оператор, используйте метод asQObject () или аналогичный).

...