IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qt Discussion :

Interface de plug-in héritant de QObject ?


Sujet :

Qt

  1. #1
    Membre confirmé

    Inscrit en
    Décembre 2009
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 170
    Par défaut Interface de plug-in héritant de QObject ?
    Salut à tous,

    J'ai voulu créer une interface de plugins héritant de QObject pour l'équiper de signaux et slots mais ça ne marche pas à la compilation de l'interface. Sans hériter de QObject ça a toujours marché sans problèmes.

    Quelqu'un aurait une idée sur le problème ?

  2. #2
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2006
    Messages : 507
    Par défaut
    Bonjour,

    Un peu de code serait le bienvenue... Ou au moins l'erreur exact du compilateur...

  3. #3
    Membre confirmé

    Inscrit en
    Décembre 2009
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 170
    Par défaut
    L'interface :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include <qplugin.h>
    class Interface2 : public QObject
    {
    	Q_OBJECT
    public:
    	Interface2(){}
    	virtual ~Interface2(){}
    	virtual void aFunction()=0;
    };
    Q_DECLARE_INTERFACE(Interface2,"Interface2")
    Le plugin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class Plugin2 : public Interface2
    {
    	Q_OBJECT
    	Q_INTERFACES(Interface2)
    public:
    	Plugin2();
    	virtual ~Plugin2();
    	void aFunction();
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Plugin2:: Plugin2(){}
    Plugin2:: ~Plugin2(){}
    void Plugin2::aFunction(){}
     
    Q_EXPORT_PLUGIN2(Plugin2,Plugin2)
    L'erreur dans Interface2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    E:\Etudes\MVASpike_workspace\Testplugin\plugin2/../src/interface2.h:9: undefined reference to `vtable for Interface2'
    debug/moc_plugin2.o:E:\Etudes\MVASpike_workspace\Testplugin\plugin2/debug/moc_plugin2.cpp:61: undefined reference to `Interface2::qt_metacast(char const*)'
    debug/moc_plugin2.o:E:\Etudes\MVASpike_workspace\Testplugin\plugin2/debug/moc_plugin2.cpp:66: undefined reference to `Interface2::qt_metacall(QMetaObject::Call, int, void**)'
    debug/moc_plugin2.o:moc_plugin2.cpp: (.rdata+0x0): undefined reference to `Interface2::staticMetaObject'

  4. #4
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2006
    Messages : 507
    Par défaut
    Merci d'utiliser les balises [ code ] [ / code ] pour afficher du code (icone '#') !

    Il semblerait que le fichier moc ne soit pas compiler ou du moins pas lier dans le binaire... Quel IDE / Compilateur utilises-tu ? N'as-tu pas oublier de passer un coup de compilateur moc ?

  5. #5
    Membre confirmé

    Inscrit en
    Décembre 2009
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 170
    Par défaut
    J'utilise eclipse / mingw. Même résultat avec Qt Creator.
    Je ne pense avoir rien oublié. Ca compile quand Interface2 n'hérite pas de QObjet.

  6. #6
    Membre confirmé

    Inscrit en
    Décembre 2009
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 170
    Par défaut
    Personne n'a eu le même problème ?
    Au pire, je pourrais déléguer l'émission des signaux et les slots à un objet à l'intérieur du plugin mais bon, ce n'est pas très clean comme approche dans ce cas ...

  7. #7
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2006
    Messages : 507
    Par défaut
    Je crois que tu ne link pas le code de Interface2 avec ton plugin... D'après les erreurs du compilateurs, c'est le fichier moc de Interface2 qui n'est pas lié avec ton binaire... est-ce qu'il est bien généré ?

  8. #8
    Membre expérimenté
    Avatar de Niak74
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    271
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2007
    Messages : 271
    Par défaut
    Selon la doc concernant les plugins Qt, l'interface d'un plugin ne doit pas dériver de QObject (car ça pose ensuite des problèmes d'héritage multiple de QObject, il est en effet impossible de dériver deux fois de QObject).

    Personnellement, pour contourner le problème, j'ai défini une fonction setObject(MonObjet*); dans mon interface qui permet de se servir de tout le stuff disponible via QObject (il me fallait en l'occurrence des signaux). Tu as juste à donner connaissance à ton plugin et à ton application du header de la classe que tu passes en paramètre à setObjet()

  9. #9
    Membre confirmé

    Inscrit en
    Décembre 2009
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 170
    Par défaut
    Merci pour la réponse.
    Je marque comme résolu.

  10. #10
    Membre confirmé

    Inscrit en
    Décembre 2009
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 170
    Par défaut
    Finalement, j'ai trouvé une solution plus simple et plus intéressante.
    En effet, les plugins qui sont une implémentations de classes abstraites héritent de QObject sans pouvoir utiliser les signaux et slots (enfin si, mais l'application principale ne les connait pas). Du coup, au lieu d'écrire un plugin qui implémente une classe abstraire, je considère qu'un plugin est un objet qui fournit une instance d'une classe qui implémente une classe abstraite. Je m'explique, voici la classe dont les plugins devaient hériter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class AbstractClass
    {
    public:
    	AbstractClass(){}
    	virtual ~AbstractClass(){}
    	virtual void aFunction()=0;
    };
    Après j'ajoute une seconde classe qui est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class AbstractClassLoader
    {
    public:
    	AbstractClassLoader(){}
    	virtual ~AbstractClassLoader(){}
    	virtual AbstractClass * load()=0;
    };
    Q_DECLARE_INTERFACE(AbstractClassLoader,"AbstractClassLoader")
    Comme on le voit, cette classe est une interface de plugins. Et maintenant du coté du plugin, on fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class AbstractClassImplementaion :  public AbstractClass
    {
    public:
    	AbstractClassImplementaion(){}
    	virtual ~AbstractClassImplementaion(){}
    	void aFunction()
    	{
    		qDebug()<<"It works";
    	}
    };
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class MyLoader : public QObject, public AbstractClassLoader
    {
    	Q_OBJECT
    	Q_INTERFACES(AbstractClassLoader)
    public:
    	MyLoader();
    	virtual ~MyLoader();
    	AbstractClass  * load();
    };
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    MyLoader::MyLoader() {}
    MyLoader::~MyLoader() {}
    AbstractClass  * MyLoader::load()
    {
    	return new AbstractClassImplementaion;
    }
    Q_EXPORT_PLUGIN2(MyLoader,MyLoader)
    L'extension de l'application ici est donc MyLoader qui fournit une instance de AbstractClassImplementaion qui hérite de AbstractClass. Pour l'application principale, la vrai extension est bien sur AbstractClassImplementaion, MyLoader n'est qu'un moyen de l'obtenir. L'avantage avec cette méthode est que après, AbstractClass peut hériter de QObject sans problème et pourra donc être équipée de signaux et slots. Et si ce n'est pas le cas, AbstractClassImplementaion n'héritera pas de QObject pour rien.

    Voilà, c'est à peu près tout.

  11. #11
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Bonjour

    Perso, j'utilise 2 classes : 1 interface qui hérite de QObject (commun au programme et au plugin) et mon plugin qui dérive du premier (et donc de QObject) :

    Fichier iplugin_global.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #ifndef IPLUGIN_GLOBAL_H
    #define IPLUGIN_GLOBAL_H
    #include <QtCore/qglobal.h>
    #if defined(IPLUGIN_LIBRARY)
    #  define IPLUGIN_EXPORT Q_DECL_EXPORT
    #else
    #  define IPLUGIN_EXPORT Q_DECL_IMPORT
    #endif
    #endif // IPLUGIN_GLOBAL_H
    Fichier iplugin.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #ifndef IPLUGIN_H
    #define IPLUGIN_H
    #include "iplugin_global.h"
    #include <QObject>
    class IPLUGIN_EXPORT IPlugin : public QObject
      {
        Q_OBJECT
        public:
          IPlugin();
          virtual ~IPlugin() = 0;
          virtual bool initialize(QString* errorString) = 0;
      };
    #endif // IPLUGIN_H
    Fichier iplugin.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include "iplugin.h"
    IPlugin::IPlugin()
      : QObject()
    {
    }
    Il faut ajouter dans le fichier .pro du programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DEFINES += IPLUGIN_LIBRARY
    Fichier plugin.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #ifndef PLUGIN_H
    #define PLUGIN_H
    #include "plugin_global.h"
    #include "iplugin.h"
      class Plugin : public IPlugin
      {
        Q_OBJECT
        public:
          bool initialize();
      };
    Fichier plugin.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include "plugin.h"
    #include <QtPlugin>
    bool Plugin::initialize()
    {
      // on initialise
      return true;
    }
    Q_EXPORT_PLUGIN(Plugin)
    Pour charger le plugin, par exemple dans le main.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        QPluginLoader loader(name);
        QObject* object = loader.instance();
        if(object)
        {
          IPlugin* plugin = qobject_cast<IPlugin*>(object);
          if(plugin) plugin->initialize();
        }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Masquer l'interface du plug-in acrobat
    Par Lagnio dans le forum Général Conception Web
    Réponses: 0
    Dernier message: 17/08/2010, 11h13
  2. plug in pour les interfaces
    Par amazircool dans le forum Graphisme
    Réponses: 2
    Dernier message: 26/12/2007, 14h32
  3. Réponses: 8
    Dernier message: 18/09/2005, 19h45
  4. existe il un plug-in de construction d'interface graphiqu
    Par adel25 dans le forum Eclipse Java
    Réponses: 4
    Dernier message: 09/08/2005, 09h45
  5. Réponses: 2
    Dernier message: 10/06/2002, 11h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo