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. The drawback of signal/slots ?
Forum Updated to NodeBB v4.3 + New Features

The drawback of signal/slots ?

Scheduled Pinned Locked Moved Unsolved General and Desktop
23 Posts 6 Posters 5.9k Views 4 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.
  • V Offline
    V Offline
    VincentLiu
    wrote on last edited by
    #1

    Hi everyone,

    We know that signal/slots is one of the significant features in QT. Every time we tend to use it, we have to emit a signal from A and the receiver B capture the signal using slots. After processing, B emit a signal with the processed result and A capture it using its slots.

    // In A class:
    emit AtoBSignal(param1, param2, ...);
    
    // In B class:
    void AtoBSlot(param1, parm2, ...)
    {
       // do something
       Result resultObj = .....;
    
       emit BtoASignal(resultObj);
    }
    
    // In A class:
    
    Result resultObj;
    void BtoASlot(Result resultObj)
    {
        // get the result and do something later
        this->resultObj = resultObj;
    }
    
    

    Is it the best way using signal/slot ? I mean, two passes (foward and back) to complete one communication. Comparing to general class instances, we can simply invoke and get the result in one sentence such as:

    resultObj = obj.query(param1, param2, ...)
    

    Please correct me if I am wrong. If it is correct, then it causes several class variables such as resultObj depicted above since the resultObj might be used later in different function. Is it the burden by signal/slot scheme or actually I miss some information about it ? Thanks ~~

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by VRonin
      #2

      I think in the code above the main burden is the pass-by-value in your signal and slots rather than the mechanism itself. convert the arguments to const references in both signals and slots, or even better, rvalue references if Result supports move semantic in any meaningful way

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

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

        Hi,

        To add to @VRonin, can you describe your use case more completely ?

        From a quick read, it looks like you are trying to replace direct calls with signals and slots everywhere even when not needed.

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

        V 1 Reply Last reply
        0
        • VRoninV VRonin

          I think in the code above the main burden is the pass-by-value in your signal and slots rather than the mechanism itself. convert the arguments to const references in both signals and slots, or even better, rvalue references if Result supports move semantic in any meaningful way

          V Offline
          V Offline
          VincentLiu
          wrote on last edited by
          #4

          @VRonin Thanks for your opinion. Is using const reference or rvalue better than pass by value a general sense in c++ or it is a feature of signal/slots ? Actually I have tried to use const reference such as Mat& based on OpenCV but in vain. I failed to register the type Mat& using qRegisterType(). In your memory, are the 3rd party types or custom types easy to register? I have no idea whether I have wrong code or it is actually a limitation in qRegisterType(). One of the code snippet:

          Q_DECLARE_METATYPE(Mat&)
          
          int main(int argc, char *argv[])
          {
              qRegisterMetaType<Mat&>("Mat&");
          
          }
          

          Do I make any mistake? Thanks

          VRoninV 1 Reply Last reply
          0
          • SGaistS SGaist

            Hi,

            To add to @VRonin, can you describe your use case more completely ?

            From a quick read, it looks like you are trying to replace direct calls with signals and slots everywhere even when not needed.

            V Offline
            V Offline
            VincentLiu
            wrote on last edited by
            #5

            @SGaist Thanks for your reply. I usually need signal/slots when the objects are in different threads. For example, one in GUI thread and the other in another thread reading frame from the camera. I want to send the image read to the GUI. Signal/slots is a must in this case, is that correct ???

            1 Reply Last reply
            0
            • V VincentLiu

              @VRonin Thanks for your opinion. Is using const reference or rvalue better than pass by value a general sense in c++ or it is a feature of signal/slots ? Actually I have tried to use const reference such as Mat& based on OpenCV but in vain. I failed to register the type Mat& using qRegisterType(). In your memory, are the 3rd party types or custom types easy to register? I have no idea whether I have wrong code or it is actually a limitation in qRegisterType(). One of the code snippet:

              Q_DECLARE_METATYPE(Mat&)
              
              int main(int argc, char *argv[])
              {
                  qRegisterMetaType<Mat&>("Mat&");
              
              }
              

              Do I make any mistake? Thanks

              VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by
              #6

              @VincentLiu said in The drawback of signal/slots ?:

              using const reference or rvalue better than pass by value a general sense in c++ or it is a feature of signal/slots ?

              It's general in C++ but, given you are not familiar with them I'd not meddle with move semantics for now, stick to the const reference

              qRegisterMetaType<Mat&>("Mat&");

              You have to register the type, not the reference, also you need to declare the metatype first with Q_DECLAREMETATYPE

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              V 1 Reply Last reply
              0
              • VRoninV VRonin

                @VincentLiu said in The drawback of signal/slots ?:

                using const reference or rvalue better than pass by value a general sense in c++ or it is a feature of signal/slots ?

                It's general in C++ but, given you are not familiar with them I'd not meddle with move semantics for now, stick to the const reference

                qRegisterMetaType<Mat&>("Mat&");

                You have to register the type, not the reference, also you need to declare the metatype first with Q_DECLAREMETATYPE

                V Offline
                V Offline
                VincentLiu
                wrote on last edited by VincentLiu
                #7

                @VRonin
                Actually I have already done something like:

                Q_DECLARE_METATYPE(Mat)
                int main(int argc, char *argv[])
                {
                    qRegisterMetaType<Mat>("Mat");
                    .....
                }
                

                Then I can successfully emit signal with Mat but not Mat&. Is it what you mean? If so, do I miss anything else? Thanks

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

                  @VincentLiu Yes, that's a valid use case.

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

                  V 1 Reply Last reply
                  1
                  • SGaistS SGaist

                    @VincentLiu Yes, that's a valid use case.

                    V Offline
                    V Offline
                    VincentLiu
                    wrote on last edited by
                    #9

                    @SGaist Hi, should I be able to use something like

                    emit AtoBSignal(Mat& mat);
                    

                    after I registered the type Mat like the code snippet above?

                    VRoninV 1 Reply Last reply
                    0
                    • V VincentLiu

                      @SGaist Hi, should I be able to use something like

                      emit AtoBSignal(Mat& mat);
                      

                      after I registered the type Mat like the code snippet above?

                      VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on last edited by VRonin
                      #10

                      @VincentLiu No, but just because the syntax is wrong. you declare the signal with:

                      signals:
                      void AtoBSignal(Mat& mat);
                      

                      and emit it with:

                      Mat mat;
                      // do something with mat
                      emit AtoBSignal(mat);
                      

                      P.S.
                      if you do not wish to edit the original object inside the slot (as is normally the case) use const Mat& mat instead of Mat& mat for safety

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      V V 2 Replies Last reply
                      0
                      • VRoninV VRonin

                        @VincentLiu No, but just because the syntax is wrong. you declare the signal with:

                        signals:
                        void AtoBSignal(Mat& mat);
                        

                        and emit it with:

                        Mat mat;
                        // do something with mat
                        emit AtoBSignal(mat);
                        

                        P.S.
                        if you do not wish to edit the original object inside the slot (as is normally the case) use const Mat& mat instead of Mat& mat for safety

                        V Offline
                        V Offline
                        VincentLiu
                        wrote on last edited by
                        #11

                        @VRonin Sorry that I didn't check the code snippet. The real one is just what you displayed. But the error message still says that I should register the type "Mat&". Any else is important?

                        1 Reply Last reply
                        0
                        • VRoninV Offline
                          VRoninV Offline
                          VRonin
                          wrote on last edited by
                          #12

                          This is strange, could you post the entire error?

                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                          ~Napoleon Bonaparte

                          On a crusade to banish setIndexWidget() from the holy land of Qt

                          V 1 Reply Last reply
                          0
                          • VRoninV VRonin

                            This is strange, could you post the entire error?

                            V Offline
                            V Offline
                            VincentLiu
                            wrote on last edited by VincentLiu
                            #13

                            @VRonin Hi, below is the signal and slot:

                                void bgVecReadySignal(vector<Mat>& bgVec);
                            
                                void bgVecReadySlot(vector<Mat>& bgVec);
                            
                            

                            And in main.cpp:

                            int main(int argc, char *argv[])
                            {
                            
                                qDebug() << "Invoked main.cpp - " << QThread::currentThreadId();
                            
                                qRegisterMetaType<vector<Mat>>("vector<Mat>");
                                qRegisterMetaType<Mat>("Mat");
                            
                                .....
                            }
                            

                            And error message shows:

                            QObject::connect: Cannot queue arguments of type 'vector<Mat>&'
                            (Make sure 'vector<Mat>&' is registered using qRegisterMetaType().)
                            

                            Did I miss anything? Thanks

                            I just found that using Qt::DirectConnection works fine. However, is it a right way to do so ?

                            kshegunovK 1 Reply Last reply
                            0
                            • VRoninV Offline
                              VRoninV Offline
                              VRonin
                              wrote on last edited by
                              #14

                              if vector is std::vector then it's because it's not natively supported by QVariant (i.e. you have to register the vector with the meta object system) alternatively you can use QVector which is already supported

                              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                              ~Napoleon Bonaparte

                              On a crusade to banish setIndexWidget() from the holy land of Qt

                              1 Reply Last reply
                              0
                              • S Offline
                                S Offline
                                stryga42
                                wrote on last edited by stryga42
                                #15

                                Hi all, do you really think that passing by reference is fine for an asynchronous signal? Both sender and receiver could change the content but with undefined sequence. My guess is that Qt refuses to pass the reference if it is going to use an asyc signal, as it is the default for thread-spanning signals.
                                Synchronous signals are more or less simple function calls, so there it would be OK.
                                I guess this is also the major reason why Qt does not support return values in the signal/slot system.

                                VRoninV kshegunovK 2 Replies Last reply
                                0
                                • VRoninV VRonin

                                  @VincentLiu No, but just because the syntax is wrong. you declare the signal with:

                                  signals:
                                  void AtoBSignal(Mat& mat);
                                  

                                  and emit it with:

                                  Mat mat;
                                  // do something with mat
                                  emit AtoBSignal(mat);
                                  

                                  P.S.
                                  if you do not wish to edit the original object inside the slot (as is normally the case) use const Mat& mat instead of Mat& mat for safety

                                  V Offline
                                  V Offline
                                  vladstelmahovsky
                                  wrote on last edited by
                                  #16

                                  @VRonin in case of Qt:QueuedConnection is will be passed by value anyway

                                  1 Reply Last reply
                                  0
                                  • S stryga42

                                    Hi all, do you really think that passing by reference is fine for an asynchronous signal? Both sender and receiver could change the content but with undefined sequence. My guess is that Qt refuses to pass the reference if it is going to use an asyc signal, as it is the default for thread-spanning signals.
                                    Synchronous signals are more or less simple function calls, so there it would be OK.
                                    I guess this is also the major reason why Qt does not support return values in the signal/slot system.

                                    VRoninV Offline
                                    VRoninV Offline
                                    VRonin
                                    wrote on last edited by
                                    #17

                                    @stryga42 said in The drawback of signal/slots ?:

                                    Both sender and receiver could change the content

                                    If 2 threads are accessing on read/write the same variable you have to handle it manually, set up a mutex of some sort. It's not as easy as passing a reference

                                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                    ~Napoleon Bonaparte

                                    On a crusade to banish setIndexWidget() from the holy land of Qt

                                    1 Reply Last reply
                                    2
                                    • S stryga42

                                      Hi all, do you really think that passing by reference is fine for an asynchronous signal? Both sender and receiver could change the content but with undefined sequence. My guess is that Qt refuses to pass the reference if it is going to use an asyc signal, as it is the default for thread-spanning signals.
                                      Synchronous signals are more or less simple function calls, so there it would be OK.
                                      I guess this is also the major reason why Qt does not support return values in the signal/slot system.

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

                                      @stryga42 said in The drawback of signal/slots ?:

                                      Hi all, do you really think that passing by reference is fine for an asynchronous signal?

                                      It is fine because you get a reference to a copy of the original object (hence the need to do qRegisterMetaType<>().

                                      Both sender and receiver could change the content but with undefined sequence.

                                      Only with direct connections, which isn't the default accross threads.

                                      My guess is that Qt refuses to pass the reference if it is going to use an asyc signal, as it is the default for thread-spanning signals.

                                      No. You must register the type with the meta-type system, so Qt knows how to copy it when the slot-invocation event is placed in the receiving thread's event loop.

                                      Synchronous signals are more or less simple function calls, so there it would be OK.

                                      It wouldn't because you need to guard the reference manually from both threads.

                                      I guess this is also the major reason why Qt does not support return values in the signal/slot system.

                                      The major reason is because when queuing a slot for execution (as with default signal-slot connection across threads) there's no meaning to return values. You can't know when the slot will be invoked, and even if you could you will already have far surpassed the point where you can obtain a return value in the emitting thread.

                                      Read and abide by the Qt Code of Conduct

                                      S 1 Reply Last reply
                                      2
                                      • kshegunovK kshegunov

                                        @stryga42 said in The drawback of signal/slots ?:

                                        Hi all, do you really think that passing by reference is fine for an asynchronous signal?

                                        It is fine because you get a reference to a copy of the original object (hence the need to do qRegisterMetaType<>().

                                        Both sender and receiver could change the content but with undefined sequence.

                                        Only with direct connections, which isn't the default accross threads.

                                        My guess is that Qt refuses to pass the reference if it is going to use an asyc signal, as it is the default for thread-spanning signals.

                                        No. You must register the type with the meta-type system, so Qt knows how to copy it when the slot-invocation event is placed in the receiving thread's event loop.

                                        Synchronous signals are more or less simple function calls, so there it would be OK.

                                        It wouldn't because you need to guard the reference manually from both threads.

                                        I guess this is also the major reason why Qt does not support return values in the signal/slot system.

                                        The major reason is because when queuing a slot for execution (as with default signal-slot connection across threads) there's no meaning to return values. You can't know when the slot will be invoked, and even if you could you will already have far surpassed the point where you can obtain a return value in the emitting thread.

                                        S Offline
                                        S Offline
                                        stryga42
                                        wrote on last edited by stryga42
                                        #19

                                        @kshegunov
                                        Sure, return values for queued connection are quite useless., I tried to say that.
                                        But the original question is then still open; maybe the class Mat has no copy constructor available?

                                        1 Reply Last reply
                                        0
                                        • V VincentLiu

                                          @VRonin Hi, below is the signal and slot:

                                              void bgVecReadySignal(vector<Mat>& bgVec);
                                          
                                              void bgVecReadySlot(vector<Mat>& bgVec);
                                          
                                          

                                          And in main.cpp:

                                          int main(int argc, char *argv[])
                                          {
                                          
                                              qDebug() << "Invoked main.cpp - " << QThread::currentThreadId();
                                          
                                              qRegisterMetaType<vector<Mat>>("vector<Mat>");
                                              qRegisterMetaType<Mat>("Mat");
                                          
                                              .....
                                          }
                                          

                                          And error message shows:

                                          QObject::connect: Cannot queue arguments of type 'vector<Mat>&'
                                          (Make sure 'vector<Mat>&' is registered using qRegisterMetaType().)
                                          

                                          Did I miss anything? Thanks

                                          I just found that using Qt::DirectConnection works fine. However, is it a right way to do so ?

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

                                          @VincentLiu @stryga42

                                          qRegisterMetaType<Mat>();
                                          qRegisterMetaType<vector<Mat>>();
                                          

                                          should fix it, provided there's also:

                                          Q_DECLARE_METATYPE(Mat)
                                          Q_DECLARE_METATYPE(vector<Mat>)
                                          

                                          somewhere in the header(s).

                                          Read and abide by the Qt Code of Conduct

                                          V 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