Results 1 to 9 of 9

Thread: Problem with plugin signals/slots

  1. #1
    Join Date
    Apr 2009
    Posts
    63
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    Windows

    Default Problem with plugin signals/slots

    I am developing under Windows and I have a Qt plugin project that produces a dll, and I have another app that can load that dll dynamically as a plugin via the usual Qt methods. Basically what I wanted to do was have the plugin report its status back to this app that's using it (i.e. the plugin emits a signal, the app receives it via a slot). So after I successfully detect and read in the plugin (i.e. the dll file), I do the usual connect call to set up the signal/slot (which returns true), but the connection doesn't seem to actually be working, as my slot code never gets executed in the app. I tried to strip down the pertinent code below.


    UpgradeInterface.h (this is the interface a plugin extends):

    Qt Code:
    1. class UpgradeInterface : public QObject
    2. {
    3. public:
    4.  
    5. virtual ~UpgradeInterface() {}
    6. virtual bool performUpgrade() = 0;
    7.  
    8. signals:
    9. void statusUpdate(QString statusMsg);
    10. };
    11.  
    12. Q_DECLARE_INTERFACE(UpgradeInterface, "com.UpgradeInterface/1.0")
    To copy to clipboard, switch view to plain text mode 

    //----------------------------------------------------------

    UpgradePlugin.h:

    Qt Code:
    1. class UpgradePlugin : public QObject, public UpgradeInterface
    2. {
    3. Q_OBJECT
    4. Q_INTERFACES(UpgradeInterface)
    5.  
    6. public:
    7. bool performUpgrade();
    8.  
    9. signals:
    10. void statusUpdate(QString statusMsg);
    11. };
    To copy to clipboard, switch view to plain text mode 

    //----------------------------------------------------

    UpgradePlugin.cpp:

    Qt Code:
    1. bool UpgradePlugin::performUpgrade()
    2. {
    3. emit statusUpdate("Upgrade started!");
    4. return true;
    5. }
    6.  
    7. Q_EXPORT_PLUGIN2(UpgradePlugin, UpgradePlugin)
    To copy to clipboard, switch view to plain text mode 

    //-------------------------------------------------

    The following is part of the app code that detects/loads the plugin.

    MyDialog.h:

    Qt Code:
    1. class MyDialog : public QDialog
    2. {
    3. Q_OBJECT
    4. //...
    5. //...
    6. protected slots:
    7. void statusUpdateFromUpgradePlugin(QString statusMsg);
    8. };
    To copy to clipboard, switch view to plain text mode 

    //------------------------------------------------------

    MyDialog.cpp:

    Qt Code:
    1. void MyDialog::loadPlugins(QDir dir)
    2. {
    3. // Load dynamic plugins
    4.  
    5. foreach (QString fileName, dir.entryList(QDir::Files))
    6. {
    7. QPluginLoader loader(dir.absoluteFilePath(fileName));
    8. QObject *plugin = loader.instance();
    9.  
    10. if (plugin)
    11. {
    12. UpgradeInterface * iUpgrade = qobject_cast<UpgradeInterface *>(plugin);
    13. if (iUpgrade)
    14. {
    15. bool success = connect(iUpgrade, SIGNAL(statusUpdate(QString)), this, SLOT(statusUpdateFromUpgradePlugin(QString))); // returns true
    16. iUpgrade->performUpgrade();
    17. }
    18. }
    19. }
    20. }
    21.  
    22. void MyDialog::statusUpdateFromUpgradePlugin(QString statusMsg)
    23. {
    24. cout << statusMsg; // Never gets here!
    25. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Problem with plugin signals/slots

    AFAIK your code won't compile because for me code like this:
    Qt Code:
    1. QString str("asdasd");
    2. std::cout << str;
    To copy to clipboard, switch view to plain text mode 
    result in this:
    error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'QString' (or there is no acceptable conversion)
    so I don't know how do you achieved compilation, but you can tell me how to do it :]
    next thing is that maybe you forgot CONFIG += console or sth. Try using:
    Qt Code:
    1. #include <QDebug>
    2.  
    3. ...
    4.  
    5. qDebug() << statusMsg;
    To copy to clipboard, switch view to plain text mode 
    except for that everything should work in your code in my opinion
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  3. #3
    Join Date
    Apr 2009
    Posts
    63
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    Windows

    Default Re: Problem with plugin signals/slots

    I don't actually have the "cout" statement in my code... it was there just as a generic line of code. So my code does actually compile . Put anything you want there... the point I was trying to illustrate is that it simply doesn't ever get there. I put break points, try to pop up message dialogs, etc. so I know it does not actually execute... thx.

  4. #4
    Join Date
    Dec 2008
    Posts
    29
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problem with plugin signals/slots

    Hi,

    try to add Q_OBJECT to the UpgradeInterface declaration. It works written in that way in my code, I hope it will help you.

    have a nice day

  5. #5
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Problem with plugin signals/slots

    ok, I've done some research and I think, like my preposter, that you should add Q_OBJECT macro in interface declaration, and you should not redefine signal in implementation, just emit it.
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  6. #6
    Join Date
    Apr 2009
    Posts
    63
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    Windows

    Default Re: Problem with plugin signals/slots

    Hmm when I add Q_OBJECT, now when I compile my UpgradePlugin project, I get:

    Error 3 error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall UpgradeInterface::metaObject(void)const " (?metaObject@UpgradeInterface@@UBEPBUQMetaObject@@ XZ) UpgradePlugin.obj UpgradePlugin
    Error 4 error LNK2001: unresolved external symbol "public: virtual void * __thiscall UpgradeInterface::qt_metacast(char const *)" (?qt_metacast@UpgradeInterface@@UAEPAXPBD@Z) UpgradePlugin.obj UpgradePlugin
    Error 5 error LNK2001: unresolved external symbol "public: virtual int __thiscall UpgradeInterface::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@UpgradeInterface@@UAEHW4Call@QMetaOb ject@@HPAPAX@Z) UpgradePlugin.obj UpgradePlugin
    Error 6 fatal error LNK1120: 3 unresolved externals ..\UpgradePlugin.dll UpgradePlugin

  7. #7
    Join Date
    Apr 2009
    Posts
    63
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    Windows

    Default Re: Problem with plugin signals/slots

    Hmm when I call emit from the class that implements UpgradeInterface (UpgradePlugin), no luck . Keep in mind UpgradePlugin is its own separate project (and produces a dll) and references the same UpgradeInterface.h file as the app (exe) project does... not that that helps, just reiterating...

    Error 3 error LNK2019: unresolved external symbol "protected: void __thiscall UpgradeInterface::statusUpdate(class QString)" (?statusUpdate@UpgradeInterface@@IAEXVQString@@@Z) referenced in function "public: virtual bool __thiscall UpgradePlugin:erformUpgrade(void)" (?performUpgrade@UpgradePlugin@@UAE_NXZ) UpgradePlugin.obj UpgradePlugin
    Error 4 error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall UpgradeInterface::metaObject(void)const " (?metaObject@UpgradeInterface@@UBEPBUQMetaObject@@ XZ) UpgradePlugin.obj UpgradePlugin
    Error 5 error LNK2001: unresolved external symbol "public: virtual void * __thiscall UpgradeInterface::qt_metacast(char const *)" (?qt_metacast@UpgradeInterface@@UAEPAXPBD@Z) UpgradePlugin.obj UpgradePlugin
    Error 6 error LNK2001: unresolved external symbol "public: virtual int __thiscall UpgradeInterface::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@UpgradeInterface@@UAEHW4Call@QMetaOb ject@@HPAPAX@Z) UpgradePlugin.obj UpgradePlugin
    Error 7 fatal error LNK1120: 4 unresolved externals ..\UpgradePlugin.dll UpgradePlugin
    Last edited by DiamonDogX; 4th June 2009 at 23:23.

  8. #8
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Problem with plugin signals/slots

    nmake clean + qmake again :]
    this works for me:
    interface.h:
    Qt Code:
    1. #ifndef INTERFACE_H
    2. #define INTERFACE_H
    3.  
    4. #include <QtPlugin>
    5.  
    6. class PluginInterface : public QObject
    7. {
    8. Q_OBJECT
    9. public:
    10. PluginInterface(QObject *parent) : QObject(parent) {}
    11. virtual void someMethod() = 0;
    12. signals:
    13. void someSignal();
    14. };
    15.  
    16. Q_DECLARE_INTERFACE(PluginInterface, "pl.faldzip.PluginInterface")
    17. #endif // INTERFACE_H
    To copy to clipboard, switch view to plain text mode 
    myplugin.h:
    Qt Code:
    1. #ifndef MYPLUGIN_H
    2. #define MYPLUGIN_H
    3.  
    4. #include "plugin1_global.h"
    5. #include "interface.h"
    6.  
    7. class MyPlugin : public PluginInterface
    8. {
    9. Q_OBJECT
    10. Q_INTERFACES(PluginInterface)
    11. public:
    12. MyPlugin(QObject *parent = 0);
    13. void someMethod();
    14. };
    15.  
    16. #endif // MYPLUGIN_H
    To copy to clipboard, switch view to plain text mode 
    myplugin.cpp:
    Qt Code:
    1. #include "myplugin.h"
    2.  
    3. MyPlugin::MyPlugin(QObject *parent)
    4. : PluginInterface(parent)
    5. {
    6. }
    7.  
    8. void MyPlugin::someMethod()
    9. {
    10. emit someSignal();
    11. }
    12.  
    13. Q_EXPORT_PLUGIN2(myplugin, MyPlugin);
    To copy to clipboard, switch view to plain text mode 

    and this was one project (with pro file containing TEMPLATE = lib and CONFIG += plugin),
    and second project - app project:
    main.cpp:
    Qt Code:
    1. #include <QtGui>
    2. #include <QtCore>
    3. #include <QtPlugin>
    4. #include "interface.h"
    5.  
    6. class SomeClass : public QObject
    7. {
    8. Q_OBJECT
    9. public:
    10. SomeClass(PluginInterface *pi, QObject *parent = 0) : QObject(parent), m_pi(pi) { connect(m_pi, SIGNAL(someSignal()), SLOT(someSlot2())); }
    11. public slots:
    12. void someSlot() { m_pi->someMethod(); }
    13. void someSlot2() { qDebug("someSlot2"); }
    14. private:
    15. PluginInterface *m_pi;
    16. };
    17.  
    18. int main(int argc, char *argv[])
    19. {
    20. QApplication a(argc, argv);
    21. QPluginLoader loader(a.applicationDirPath() + QDir::separator() + "plugin1.dll");
    22. QObject *obj = loader.instance();
    23. PluginInterface *pi = qobject_cast<PluginInterface *>(obj);
    24. if (!pi)
    25. {
    26. qDebug("plugin error");
    27. return 1;
    28. }
    29. QPushButton pb("Button");
    30. SomeClass sc(pi, &pb);
    31. pb.connect(&pb, SIGNAL(clicked()), &sc, SLOT(someSlot()));
    32. pb.show();
    33. return a.exec();
    34. }
    35.  
    36. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 
    so it shows a button, and when I click on it, it's callingSomeClass::someSlot() which is calling PluginInterface::someMethod(), whis is emitting someSignal() connected to someSlot2() so the "someSlot2" appears on the screen.
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  9. #9
    Join Date
    Apr 2009
    Posts
    63
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    Windows

    Default Re: Problem with plugin signals/slots

    Thanks for the help... finally got it!

    One problem was the Q_OBJECT thing... but after adding that I got some link errors, as I mentioned. Basically I reorganized my projects so that the UpgradeInterface was in its own separate project (lib), and I had the plugin project and app project both reference that project. Works

Similar Threads

  1. Problem building dynamic plugin
    By javd in forum Qt Programming
    Replies: 3
    Last Post: 6th April 2009, 19:02
  2. problem loading custom plugin on Qt Designer 4
    By raman_31181 in forum Qt Tools
    Replies: 18
    Last Post: 26th September 2008, 10:42
  3. plugin loading problem
    By naresh in forum Qt Programming
    Replies: 6
    Last Post: 9th June 2007, 20:05
  4. Qt4 win opensource + mysql plugin
    By vr in forum Installation and Deployment
    Replies: 3
    Last Post: 25th May 2007, 10:01
  5. Replies: 7
    Last Post: 3rd February 2006, 11:20

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.