Bonjour,

Je travaille actuellement sur le développement d'une application et de plugins. Il semble que les connexions Signal/Slot entre plugin et application soient impossible. J'ai parcouru pas mal de forums et tentés pas mal de choses sans succès (cast dynamique, appel implicite, ect...).

J'ai trouvé une solution qui permet d'obtenir le résultat souhaité (c'est à dire la connexion entre un signal du plugin et un slot de l'application) sans trop de lignes de codes, et sans trop complexifier la chose. Je souhaiterai votre avis sur l'idée, et peut être une alternative à laquelle je ne pense pas...

Nous avons 3 éléménts : un plugin qui émet des signaux, une application qui charge le plugin et qui contient des slots, et une interface pour le plugin, celle-ci sans signaux (car ne pouvant dériver aussi de QObject). L'idée est d'ajouter une sorte de handler de signal qui sera instancié par l'application, qui possédera l'ensemble des signaux du plugins, et qui se chargera de transmettre les signaux émis par le plugin.

En pratique, ça donne ceci :

PluginInterface.h :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
#include <QWidget>
 
class PluginInterfaceSignalHandler : public QObject
{
    Q_OBJECT
 
public:
    PluginInterfaceSignalHandler(QObject * parent = 0) : QObject(parent){}
 
signals:
    void pluginSignal();
};
 
class PluginInterface
{
public:
    virtual void setSignalHandler(PluginInterfaceSignalHandler *) = 0;
    virtual void externalFunction() = 0;
};
 
Q_DECLARE_INTERFACE(PluginInterface, "example.project.PluginInterface/1.0")
Plugin.h :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
#include <QtGui>
#include "PluginInterface.h"
 
class Plugin : public QWidget, PluginInterface
{
    Q_OBJECT
    Q_INTERFACES(PluginInterface)
 
    //------------------------//
    //-- External functions --//
    //------------------------//
 
public:
    PluginInterface(QWidget* parent = 0);
 
    void setSignalHandler(PluginInterfaceSignalHandler *);
    void externalFunction();
 
signals:
    void pluginSignal();
 
    //-----------------------//
    //-- Internal elements --//
    //-----------------------//
private:
    int privatePluginAttribute;
    void privatePluginFunction();
};
Plugin.cpp :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
 
void Plugin::setSignalHandler(PluginInterfaceSignalHandler * handler)
{
    handler->disconnect();
 
    QObject::connect(this, SIGNAL(pluginSignal()), handler, SIGNAL(pluginSignal()));
}
Application.cpp :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
void Application::configurePugin()
{
    QString pluginsDirPath = "Plugins";
    PluginInterface pluginInterface = 0;
 
    QDir pluginsDir(pluginsDirPath);
    foreach(QString fileName, pluginsDir.entryList(QDir::Files))
    {
        QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
        QObject * plugin = pluginLoader.instance();
        if(plugin)
        {
            pluginInterface = qobject_cast<PluginInterface*>(plugin);
            if(!pluginInterface)
            {
                qDebug() << "Unable to load Plugin !";
                return;
            }
        }
    }
 
    //-- Make connections --//
    PluginInterfaceSignalHandler * pluginInterfaceSignalHandler = new PluginInterfaceSignalHandler(this);
    pluginInterface->setSignalHandler(pluginInterfaceSignalHandler);
 
    QObject::connect(pluginInterfaceSignalHandler, SIGNAL(pluginSignal()), this, SLOT(applicationSlot()));
}