Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Sharing data between application and module

Sharing data between application and module

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 4 Posters 1.7k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mgreenish
    wrote on last edited by
    #1

    I have written a GUI application and then a module (dll/dylib) to share data with a web app. I can share data from the main application to the module by declaring a function in the interface class and then calling that function from the main application.

    Now I want to update a field in the main application window when the module receives data from the web server. So in this case, the module would send data back to the main application. However, I haven't found a way to link a function in the main application to the module. I've looked at IPC's but that seems relatively heavy. Is there an easier way to do it?

    kshegunovK 1 Reply Last reply
    0
    • M mgreenish

      I have written a GUI application and then a module (dll/dylib) to share data with a web app. I can share data from the main application to the module by declaring a function in the interface class and then calling that function from the main application.

      Now I want to update a field in the main application window when the module receives data from the web server. So in this case, the module would send data back to the main application. However, I haven't found a way to link a function in the main application to the module. I've looked at IPC's but that seems relatively heavy. Is there an easier way to do it?

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by
      #2

      Define a signal in a class that's exposed to the application and connect it to the slot in the GUI code. For all intents and purposes the application code and the shared library are the same code.

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      4
      • M Offline
        M Offline
        mgreenish
        wrote on last edited by mgreenish
        #3

        I don't think it is possible to make an interface class extend QObject. I have tried that in the past but it doesn't work for some reason, can't remember why. Without QObject, I can't use the connect calls, I believe.

        kshegunovK 1 Reply Last reply
        0
        • M mgreenish

          I don't think it is possible to make an interface class extend QObject. I have tried that in the past but it doesn't work for some reason, can't remember why. Without QObject, I can't use the connect calls, I believe.

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          @mgreenish said in Sharing data between application and module:

          I don't think it is possible to make an interface class extend QObject.

          It is, that's how the plugins get loaded to begin with.

          I have tried that in the past but it doesn't work for some reason, can't remember why.

          You have had some other error then.

          Without QObject, I can't use the connect calls, I believe.

          Indeed.

          Read and abide by the Qt Code of Conduct

          M 1 Reply Last reply
          3
          • kshegunovK kshegunov

            @mgreenish said in Sharing data between application and module:

            I don't think it is possible to make an interface class extend QObject.

            It is, that's how the plugins get loaded to begin with.

            I have tried that in the past but it doesn't work for some reason, can't remember why.

            You have had some other error then.

            Without QObject, I can't use the connect calls, I believe.

            Indeed.

            M Offline
            M Offline
            mgreenish
            wrote on last edited by mgreenish
            #5

            So I found that with a dynamic cast, I can connect the main application to the plugin as follows :

            QObject::connect( this, SIGNAL(effectsSent(QJsonDocument)), dynamic_cast< QObject * >(reactionsserverInterface), SLOT(saveReactionFile(QJsonDocument)) );
            

            even if the interface does not extend QObject. reactionsserverInterface is the plugin object. This works for sending signals from the main app to the plugin, meaning the plugin gets the signal and acts on it.

            However, in the other direction,

            QObject::connect( dynamic_cast< QObject * >(reactionsserverInterface), SIGNAL(requestingReactionFile), this, SLOT(rsSaveReactionFile()));
            

            it compiles but doesn't work. My application doesn't seem to receive the signals from the plugin. I did step through the plugin code and it is getting to the emit call but in the case above, the breakpoints in rsSaveReactionFile don't get triggered.

            The plugin signal requestingReactionFile is exposed to the main application in the interface as below:

            signals:
            virtual void requestingReactionFile() = 0;
            

            so everything compiles, but it does not work.

            Again, when my interface class extends QObject, I get errors when compiling my plugin wherever I use connect even for signals/slots that are local to my plugin, as below:

                connect( ui->configButton, SIGNAL(clicked(bool)), rsPluginObject, SLOT(displayConfigDialog()) );
            
            ambiguous conversion from derived class 'ReactionsServerPlugin' to base class 'const QObject':
                class ReactionsServerPlugin -> class QObject
                class ReactionsServerPlugin -> class ReactionsServerInterface -> class QObject
                connect( rsPluginObject, SIGNAL(reactionFileNameUpdated(QString)), this, SLOT(setCurrentReactionFileName(QString)) );
            

            The connect above is called from a QDialog object that is a part of the plugin and the rsPluginObject is the plugin object that instantiates that QDialog object.

            Do plugin signals not get injected into the main application event loop?

            JonBJ kshegunovK 2 Replies Last reply
            0
            • M mgreenish

              So I found that with a dynamic cast, I can connect the main application to the plugin as follows :

              QObject::connect( this, SIGNAL(effectsSent(QJsonDocument)), dynamic_cast< QObject * >(reactionsserverInterface), SLOT(saveReactionFile(QJsonDocument)) );
              

              even if the interface does not extend QObject. reactionsserverInterface is the plugin object. This works for sending signals from the main app to the plugin, meaning the plugin gets the signal and acts on it.

              However, in the other direction,

              QObject::connect( dynamic_cast< QObject * >(reactionsserverInterface), SIGNAL(requestingReactionFile), this, SLOT(rsSaveReactionFile()));
              

              it compiles but doesn't work. My application doesn't seem to receive the signals from the plugin. I did step through the plugin code and it is getting to the emit call but in the case above, the breakpoints in rsSaveReactionFile don't get triggered.

              The plugin signal requestingReactionFile is exposed to the main application in the interface as below:

              signals:
              virtual void requestingReactionFile() = 0;
              

              so everything compiles, but it does not work.

              Again, when my interface class extends QObject, I get errors when compiling my plugin wherever I use connect even for signals/slots that are local to my plugin, as below:

                  connect( ui->configButton, SIGNAL(clicked(bool)), rsPluginObject, SLOT(displayConfigDialog()) );
              
              ambiguous conversion from derived class 'ReactionsServerPlugin' to base class 'const QObject':
                  class ReactionsServerPlugin -> class QObject
                  class ReactionsServerPlugin -> class ReactionsServerInterface -> class QObject
                  connect( rsPluginObject, SIGNAL(reactionFileNameUpdated(QString)), this, SLOT(setCurrentReactionFileName(QString)) );
              

              The connect above is called from a QDialog object that is a part of the plugin and the rsPluginObject is the plugin object that instantiates that QDialog object.

              Do plugin signals not get injected into the main application event loop?

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @mgreenish said in Sharing data between application and module:
              The only bit I know about is:

              Again, when my interface class extends QObject, I get errors when compiling my plugin wherever I use connect even for signals/slots that are local to my plugin, as below:

                  connect( ui->configButton, SIGNAL(clicked(bool)), rsPluginObject, SLOT(displayConfigDialog()) );
              
              ambiguous conversion from derived class 'ReactionsServerPlugin' to base class 'const QObject':
                  class ReactionsServerPlugin -> class QObject
                  class ReactionsServerPlugin -> class ReactionsServerInterface -> class QObject
                  connect( rsPluginObject, SIGNAL(reactionFileNameUpdated(QString)), this, SLOT(setCurrentReactionFileName(QString)) );
              

              The connect above is called from a QDialog object that is a part of the plugin and the rsPluginObject is the plugin object that instantiates that QDialog object.

              That won't stop the principle working, it's just a compilation issue to get round. I presume your ReactionsServerPlugin inherits directly from QObject, but it also inherits from ReactionsServerInterface , which inherits from QObject too. So you have to tell the compiler which "route" you want it to take to reach a 'const QObject'. Right? Sorry if you already know this.

              Now I'm not a C++er, but there must be a syntax to disambiguate. I don't even know if it matters which of the two "routes" you tell the compiler to take. But with no testing/evidence from me, wouldn't it work if for instance you wrote:

              dynamic_cast< QObject * >( dynamic_cast< ReactionsServerInterface * >(rsPluginObject) )
              

              ?

              [In this case you presumably don't even need the outer QObject* cast, so dynamic_cast< ReactionsServerInterface * >(rsPluginObject) would probably be the same.]

              1 Reply Last reply
              0
              • M mgreenish

                So I found that with a dynamic cast, I can connect the main application to the plugin as follows :

                QObject::connect( this, SIGNAL(effectsSent(QJsonDocument)), dynamic_cast< QObject * >(reactionsserverInterface), SLOT(saveReactionFile(QJsonDocument)) );
                

                even if the interface does not extend QObject. reactionsserverInterface is the plugin object. This works for sending signals from the main app to the plugin, meaning the plugin gets the signal and acts on it.

                However, in the other direction,

                QObject::connect( dynamic_cast< QObject * >(reactionsserverInterface), SIGNAL(requestingReactionFile), this, SLOT(rsSaveReactionFile()));
                

                it compiles but doesn't work. My application doesn't seem to receive the signals from the plugin. I did step through the plugin code and it is getting to the emit call but in the case above, the breakpoints in rsSaveReactionFile don't get triggered.

                The plugin signal requestingReactionFile is exposed to the main application in the interface as below:

                signals:
                virtual void requestingReactionFile() = 0;
                

                so everything compiles, but it does not work.

                Again, when my interface class extends QObject, I get errors when compiling my plugin wherever I use connect even for signals/slots that are local to my plugin, as below:

                    connect( ui->configButton, SIGNAL(clicked(bool)), rsPluginObject, SLOT(displayConfigDialog()) );
                
                ambiguous conversion from derived class 'ReactionsServerPlugin' to base class 'const QObject':
                    class ReactionsServerPlugin -> class QObject
                    class ReactionsServerPlugin -> class ReactionsServerInterface -> class QObject
                    connect( rsPluginObject, SIGNAL(reactionFileNameUpdated(QString)), this, SLOT(setCurrentReactionFileName(QString)) );
                

                The connect above is called from a QDialog object that is a part of the plugin and the rsPluginObject is the plugin object that instantiates that QDialog object.

                Do plugin signals not get injected into the main application event loop?

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by kshegunov
                #7

                Your approach is wrong. You shall not derive multiple times from QObject. If your abstract class derives from QObject, i.e. it's not a pure interface, then you need to put in a dynamic library that is linked both with the application and the plugin. However I really don't see a reason for you to have your interface derive from QObject. Could you elaborate? That's needed for the actual implementation, but not for the abstract class in principle.

                @JonB said in Sharing data between application and module:

                Now I'm not a C++er, but there must be a syntax to disambiguate. I don't even know if it matters which of the two "routes" you tell the compiler to take. But with no testing/evidence from me, wouldn't it work if for instance you wrote

                There is, but unfortunately it's much more complicated than that. What is needed in standard C++ is virtual inheritance, however:

                1. For the 99.5% of cases it's neither needed nor a good thing to do.
                2. It's not supported for QObject derived classes.

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                3
                • M Offline
                  M Offline
                  mgreenish
                  wrote on last edited by
                  #8

                  So thank you kshegunov for confirming that my interface class should not derive QObject. I did find my mistake above, very slight but enough to not throw any warnings yet still not work. The following code:

                  QObject::connect( dynamic_cast< QObject * >(reactionsserverInterface), SIGNAL(requestingReactionFile), this, SLOT(rsSaveReactionFile()));
                  

                  should be

                  QObject::connect( dynamic_cast< QObject * >(reactionsserverInterface), SIGNAL(requestingReactionFile()), this, SLOT(rsSaveReactionFile()));
                  

                  I just missed the () on the of the function name inside the SIGNAL() macro. Once I put that, it worked, I was able to get data going both ways.

                  1 Reply Last reply
                  1
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    Hi,

                    For QObject based classes use qobject_cast.

                    You should also consider using the new Qt 5 syntax for connection, it will give you compile time warning and avoid the situation you encountered.

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    2

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved