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. Qt signal-slot duplication code avoidance

Qt signal-slot duplication code avoidance

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 4 Posters 1.3k Views
  • 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
    vernes
    wrote on last edited by vernes
    #1

    I would like to share signals and possibly slot implementations among different classes, but it seems Qt does not allow this.

    Basically I would like to have something like:

    class CommonSignals
      {
      signals:
      void mysignal();
      };
    
    class A : 
        public QObject, 
        public CommonSignals
      {
        Q_OBJECT
      public:
        void doSomething()
          {
          emit mysignal();
          }
      };
    
    
    class B : 
        public QObject, 
        public CommonSignals
      {
        Q_OBJECT
    
      public:
    
        B()
          {
          connect(&a, &A::mysignal, this, &B::mysignal);
          }
    
        A a;
      };
    

    So that when for some reason A emits a signal B emits the same signal too. This to avoid useless code replication and improve maintainability. In other words the goal is to make B (or other classes) extend different classes, e.g. CommonSignals, CommonSignals2, CommonSignals3 etc so that you can use these CommonSignalsX for different applications withour re-writing the same code every time.

    Any ideas?

    PS I've tried also with virtual inheritance but I've got classical qmake problems

    CP71C 1 Reply Last reply
    0
    • A Offline
      A Offline
      arsinte_andrei
      wrote on last edited by
      #2

      you made me confused about what you need - you can have many classes that emit the very same name signal (like readyread - in qtcpsocket, qabstractsocket, qudpsocket and so on...) but you make the difference between them when you use connect... - you have to select the sender.. so how can it be any confusions at all??
      please be a bit more specific...

      V 1 Reply Last reply
      0
      • V vernes

        I would like to share signals and possibly slot implementations among different classes, but it seems Qt does not allow this.

        Basically I would like to have something like:

        class CommonSignals
          {
          signals:
          void mysignal();
          };
        
        class A : 
            public QObject, 
            public CommonSignals
          {
            Q_OBJECT
          public:
            void doSomething()
              {
              emit mysignal();
              }
          };
        
        
        class B : 
            public QObject, 
            public CommonSignals
          {
            Q_OBJECT
        
          public:
        
            B()
              {
              connect(&a, &A::mysignal, this, &B::mysignal);
              }
        
            A a;
          };
        

        So that when for some reason A emits a signal B emits the same signal too. This to avoid useless code replication and improve maintainability. In other words the goal is to make B (or other classes) extend different classes, e.g. CommonSignals, CommonSignals2, CommonSignals3 etc so that you can use these CommonSignalsX for different applications withour re-writing the same code every time.

        Any ideas?

        PS I've tried also with virtual inheritance but I've got classical qmake problems

        CP71C Offline
        CP71C Offline
        CP71
        wrote on last edited by
        #3

        @vernes
        Hi,
        I think in CommonSignals you lost Q_OBJECT macro

        V 1 Reply Last reply
        0
        • CP71C CP71

          @vernes
          Hi,
          I think in CommonSignals you lost Q_OBJECT macro

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

          @CP71 said in Qt signal-slot duplication code avoidance:

          @vernes
          Hi,
          I think in CommonSignals you lost Q_OBJECT macro

          Yep, it's just pseudocode, just to give you an idea

          KillerSmathK CP71C 2 Replies Last reply
          1
          • A arsinte_andrei

            you made me confused about what you need - you can have many classes that emit the very same name signal (like readyread - in qtcpsocket, qabstractsocket, qudpsocket and so on...) but you make the difference between them when you use connect... - you have to select the sender.. so how can it be any confusions at all??
            please be a bit more specific...

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

            @arsinte_andrei said in Qt signal-slot duplication code avoidance:

            you made me confused about what you need - you can have many classes that emit the very same name signal (like readyread - in qtcpsocket, qabstractsocket, qudpsocket and so on...) but you make the difference between them when you use connect... - you have to select the sender.. so how can it be any confusions at all??
            please be a bit more specific...

            I'm speaking about inheriting from classes. Qt seems having problems when you inherit from multiple classes.
            If that class B was extending CommonSignals and CommonSignals2, both of them containing signals and slots, I'm sure I would get compilation problems

            A 1 Reply Last reply
            0
            • V vernes

              @CP71 said in Qt signal-slot duplication code avoidance:

              @vernes
              Hi,
              I think in CommonSignals you lost Q_OBJECT macro

              Yep, it's just pseudocode, just to give you an idea

              KillerSmathK Offline
              KillerSmathK Offline
              KillerSmath
              wrote on last edited by KillerSmath
              #6

              @vernes
              QObject don't support multiple inheritances because of MOC. I suggest you to think in a hasA relationship instead of isA.

              Virtual inheritance with QObject is not supported.

              @Computer Science Student - Brazil
              Web Developer and Researcher
              “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

              V 1 Reply Last reply
              2
              • V vernes

                @arsinte_andrei said in Qt signal-slot duplication code avoidance:

                you made me confused about what you need - you can have many classes that emit the very same name signal (like readyread - in qtcpsocket, qabstractsocket, qudpsocket and so on...) but you make the difference between them when you use connect... - you have to select the sender.. so how can it be any confusions at all??
                please be a bit more specific...

                I'm speaking about inheriting from classes. Qt seems having problems when you inherit from multiple classes.
                If that class B was extending CommonSignals and CommonSignals2, both of them containing signals and slots, I'm sure I would get compilation problems

                A Offline
                A Offline
                arsinte_andrei
                wrote on last edited by
                #7

                @vernes why on earth will you have 2 different classes that are emitting the very same name signall for the very same thing? and to process the very same data at the very same time and both of them to be the inherited classes for the 3rd which is doing the very same thing?? it just doesn't make any sense at all - I've already explained to you how qsocket work.. and is processing signals from different classes that it inherited from I do not see where the confusion can be? I mean the signal slot connector in Qt is very mature and is doing a great job... there is no confusion even for the compiler this is why we have moc files - to avoid confusions...
                so your problem doesn't make any sense at least to me... I've done many classes that extend 2 or 3 classes without any problems in managing the signals from them - maybe had to reimplement some of the signals.. but that's the way it is.. you can have a look at Qt source... many times a class is not doing anything except putting together 2 classes

                V 1 Reply Last reply
                0
                • KillerSmathK KillerSmath

                  @vernes
                  QObject don't support multiple inheritances because of MOC. I suggest you to think in a hasA relationship instead of isA.

                  Virtual inheritance with QObject is not supported.

                  V Offline
                  V Offline
                  vernes
                  wrote on last edited by
                  #8

                  @KillerSmath said in Qt signal-slot duplication code avoidance:

                  Virtual inheritance with QObject i

                  Ok, I suspected that. I'm just trying to find the best solution to not repeat code.

                  Basically, in my design, B is a class that contains different classes A, C, D, E, all of them that have different signals.
                  B must just forward signals, My idea was to create signals in helper classes. E.g. ASignals, CSignals, DSignals, ESignals,
                  and do something like A : public ASignals, C : public CSignals etc. B should then extend only one QObject and all the
                  signals classes B: public QObject, ASignals, CSignals, DSignals, ESignals. Ideally I would like to do this same trick for slots.

                  Is there a way to circumvent this virtual inheritance problem in this way?

                  1 Reply Last reply
                  0
                  • A arsinte_andrei

                    @vernes why on earth will you have 2 different classes that are emitting the very same name signall for the very same thing? and to process the very same data at the very same time and both of them to be the inherited classes for the 3rd which is doing the very same thing?? it just doesn't make any sense at all - I've already explained to you how qsocket work.. and is processing signals from different classes that it inherited from I do not see where the confusion can be? I mean the signal slot connector in Qt is very mature and is doing a great job... there is no confusion even for the compiler this is why we have moc files - to avoid confusions...
                    so your problem doesn't make any sense at least to me... I've done many classes that extend 2 or 3 classes without any problems in managing the signals from them - maybe had to reimplement some of the signals.. but that's the way it is.. you can have a look at Qt source... many times a class is not doing anything except putting together 2 classes

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

                    @arsinte_andrei said in Qt signal-slot duplication code avoidance:

                    @vernes why on earth will you have 2 different classes that are emitting the very same name signall for the very same thing? and to process the very same data at the very same time and both of them to be the inherited classes for the 3rd which is doing the very same thing?? it just doesn't make any sense at all - I've already explained to you how qsocket work.. and is processing signals from different classes that it inherited from I do not see where the confusion can be? I mean the signal slot connector in Qt is very mature and is doing a great job... there is no confusion even for the compiler this is why we have moc files - to avoid confusions...
                    so your problem doesn't make any sense at least to me... I've done many classes that extend 2 or 3 classes without any problems in managing the signals from them - maybe had to reimplement some of the signals.. but that's the way it is.. you can have a look at Qt source... many times a class is not doing anything except putting together 2 classes

                    It doesn't make sense if you don't know the context. I'm trying to managing complexity, using different QThreads. The class that is B is a class that has to manage all the signals coming from the threads, do some stuff, and re-emitting these signals. Why this? because of maintainability / modularity, that's now too long to explain.

                    KillerSmathK 1 Reply Last reply
                    0
                    • V vernes

                      @arsinte_andrei said in Qt signal-slot duplication code avoidance:

                      @vernes why on earth will you have 2 different classes that are emitting the very same name signall for the very same thing? and to process the very same data at the very same time and both of them to be the inherited classes for the 3rd which is doing the very same thing?? it just doesn't make any sense at all - I've already explained to you how qsocket work.. and is processing signals from different classes that it inherited from I do not see where the confusion can be? I mean the signal slot connector in Qt is very mature and is doing a great job... there is no confusion even for the compiler this is why we have moc files - to avoid confusions...
                      so your problem doesn't make any sense at least to me... I've done many classes that extend 2 or 3 classes without any problems in managing the signals from them - maybe had to reimplement some of the signals.. but that's the way it is.. you can have a look at Qt source... many times a class is not doing anything except putting together 2 classes

                      It doesn't make sense if you don't know the context. I'm trying to managing complexity, using different QThreads. The class that is B is a class that has to manage all the signals coming from the threads, do some stuff, and re-emitting these signals. Why this? because of maintainability / modularity, that's now too long to explain.

                      KillerSmathK Offline
                      KillerSmathK Offline
                      KillerSmath
                      wrote on last edited by
                      #10

                      @vernes

                      You can implement a hasX (composition) relationship

                      class A : public QObject // is QObject
                      {
                          Q_OBJECT
                      public:
                          A() {}
                      signals:
                          void mySignal();
                      };
                      
                      class B : public QObject // is QObject
                      {
                          Q_OBJECT
                      public:
                          B(){}
                      
                      signals:
                          void mySignal();
                      };
                      
                      class C : public QObject // is QObject
                      {
                          Q_OBJECT
                      
                      public:
                          C()
                          {
                              connect(this, &C::sendToA, &a, &A::mySignal);
                              connect(this, &C::sendToB, &b, &B::mySignal);
                      
                              connect(&a, &A::mySignal, [](){qDebug() << "A signal emitted";});
                              connect(&b, &B::mySignal, [](){qDebug() << "B signal emitted";});
                          }
                      
                      signals:
                          void sendToA();
                          void sendToB();
                      private:
                          A a; // has A
                          B b; // has B
                      };
                      

                      @Computer Science Student - Brazil
                      Web Developer and Researcher
                      “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

                      V 1 Reply Last reply
                      2
                      • KillerSmathK KillerSmath

                        @vernes

                        You can implement a hasX (composition) relationship

                        class A : public QObject // is QObject
                        {
                            Q_OBJECT
                        public:
                            A() {}
                        signals:
                            void mySignal();
                        };
                        
                        class B : public QObject // is QObject
                        {
                            Q_OBJECT
                        public:
                            B(){}
                        
                        signals:
                            void mySignal();
                        };
                        
                        class C : public QObject // is QObject
                        {
                            Q_OBJECT
                        
                        public:
                            C()
                            {
                                connect(this, &C::sendToA, &a, &A::mySignal);
                                connect(this, &C::sendToB, &b, &B::mySignal);
                        
                                connect(&a, &A::mySignal, [](){qDebug() << "A signal emitted";});
                                connect(&b, &B::mySignal, [](){qDebug() << "B signal emitted";});
                            }
                        
                        signals:
                            void sendToA();
                            void sendToB();
                        private:
                            A a; // has A
                            B b; // has B
                        };
                        
                        V Offline
                        V Offline
                        vernes
                        wrote on last edited by
                        #11

                        @KillerSmath said in Qt signal-slot duplication code avoidance:

                        @vernes

                        You can implement a hasX (composition) relationship

                        class A : public QObject // is QObject
                        {
                            Q_OBJECT
                        public:
                            A() {}
                        signals:
                            void mySignal();
                        };
                        
                        class B : public QObject // is QObject
                        {
                            Q_OBJECT
                        public:
                            B(){}
                        
                        signals:
                            void mySignal();
                        };
                        
                        class C : public QObject // is QObject
                        {
                            Q_OBJECT
                        
                        public:
                            C()
                            {
                                connect(this, &C::sendToA, &a, &A::mySignal);
                                connect(this, &C::sendToB, &b, &B::mySignal);
                        
                                connect(&a, &A::mySignal, [](){qDebug() << "A signal emitted";});
                                connect(&b, &B::mySignal, [](){qDebug() << "B signal emitted";});
                            }
                        
                        signals:
                            void sendToA();
                            void sendToB();
                        private:
                            A a; // has A
                            B b; // has B
                        };
                        

                        Thank you for the feedback. It's my current approach, but as I said I'm trying to remove duplicated code :)

                        1 Reply Last reply
                        0
                        • V vernes

                          @CP71 said in Qt signal-slot duplication code avoidance:

                          @vernes
                          Hi,
                          I think in CommonSignals you lost Q_OBJECT macro

                          Yep, it's just pseudocode, just to give you an idea

                          CP71C Offline
                          CP71C Offline
                          CP71
                          wrote on last edited by
                          #12

                          @vernes
                          Maybe I lost something! Or I don't understand your issue!
                          You don’t need of inherit from multiple classes.

                          If I have to do something like this I would do:

                          class CommonSignals : public QObject
                          {
                          Q_OBJECT
                          public:
                          CommonSignals( QObject *parent = NULL);

                          signals:
                          void mysignal();
                          

                          };

                          class A : public CommonSignals
                          {
                          Q_OBJECT
                          public:
                          A( QObject *parent = NULL )

                          void doSomething()
                          {
                          	emit mysignal();
                          }
                          

                          };

                          class B : public CommonSignals
                          {
                          Q_OBJECT

                          public:

                          B(QObject *parent = NULL ) : CommonSignals(parent)
                          {
                            connect(&a, &A::mysignal, this, &B::mysignal);
                          }
                          
                          A a;
                          

                          };

                          Maybe I read too fast and don’t understand your issue or your code.
                          Sorry

                          1 Reply Last reply
                          0
                          • V Offline
                            V Offline
                            vernes
                            wrote on last edited by vernes
                            #13

                            @CP71 said in Qt signal-slot duplication code avoidance:

                            CommonSignals

                            Thank you for your feedback. The goal is to make B use CommonSignals1, CommonSignals2, CommonSignals3 together in the same class

                            Code example:

                            class CommonSignalsA : public QObject
                            {
                            Q_OBJECT
                            public:
                            CommonSignalsA( QObject *parent = NULL);
                            
                            signals:
                            void mysignal();
                            };
                            
                            class CommonSignalsB : public QObject
                            {
                            Q_OBJECT
                            public:
                            CommonSignalsB( QObject *parent = NULL);
                            
                            signals:
                            void mysignal2();
                            };
                            
                            class A : public CommonSignalsA
                            {
                            Q_OBJECT
                            public:
                            A( QObject *parent = NULL )
                            
                            void doSomething()
                            {
                            	emit mysignal();
                            }
                            };
                            
                            class B : public CommonSignalsB
                            {
                            Q_OBJECT
                            public:
                            B( QObject *parent = NULL )
                            
                            void doSomething2()
                            {
                            	emit mysignal2();
                            }
                            };
                            
                            class C : public CommonSignalsA,  public CommonSignalsB
                            {
                            Q_OBJECT
                            
                            public:
                            
                            C(QObject *parent = NULL ) : CommonSignalsA(parent), CommonSignalsB(parent)
                            {
                              connect(&a, &A::mysignal, this, &C::mysignal);
                            connect(&b, &B::mysignal2, this, &C::mysignal2);
                            }
                            
                            A a;
                            B b;
                            };
                            

                            Basically, my question is: is it possible to create a CommonSignals that doesn't use QObject, or however making this work with same trick.. maybe passing QObject in same way.

                            KillerSmathK 1 Reply Last reply
                            1
                            • V vernes

                              @CP71 said in Qt signal-slot duplication code avoidance:

                              CommonSignals

                              Thank you for your feedback. The goal is to make B use CommonSignals1, CommonSignals2, CommonSignals3 together in the same class

                              Code example:

                              class CommonSignalsA : public QObject
                              {
                              Q_OBJECT
                              public:
                              CommonSignalsA( QObject *parent = NULL);
                              
                              signals:
                              void mysignal();
                              };
                              
                              class CommonSignalsB : public QObject
                              {
                              Q_OBJECT
                              public:
                              CommonSignalsB( QObject *parent = NULL);
                              
                              signals:
                              void mysignal2();
                              };
                              
                              class A : public CommonSignalsA
                              {
                              Q_OBJECT
                              public:
                              A( QObject *parent = NULL )
                              
                              void doSomething()
                              {
                              	emit mysignal();
                              }
                              };
                              
                              class B : public CommonSignalsB
                              {
                              Q_OBJECT
                              public:
                              B( QObject *parent = NULL )
                              
                              void doSomething2()
                              {
                              	emit mysignal2();
                              }
                              };
                              
                              class C : public CommonSignalsA,  public CommonSignalsB
                              {
                              Q_OBJECT
                              
                              public:
                              
                              C(QObject *parent = NULL ) : CommonSignalsA(parent), CommonSignalsB(parent)
                              {
                                connect(&a, &A::mysignal, this, &C::mysignal);
                              connect(&b, &B::mysignal2, this, &C::mysignal2);
                              }
                              
                              A a;
                              B b;
                              };
                              

                              Basically, my question is: is it possible to create a CommonSignals that doesn't use QObject, or however making this work with same trick.. maybe passing QObject in same way.

                              KillerSmathK Offline
                              KillerSmathK Offline
                              KillerSmath
                              wrote on last edited by
                              #14

                              @vernes
                              One point i would like to talk about here.
                              The Software engineering warns to use the minimum coupling while maximize the cohesion of class.

                              Note: Inheritance is a 2 edged weapon, reusability is good but dependence is bad.

                              If you decide to modify a class with a high dependency level, it can break the logic of some dependent class and it can be recursive.

                              @Computer Science Student - Brazil
                              Web Developer and Researcher
                              “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

                              V 1 Reply Last reply
                              2
                              • KillerSmathK KillerSmath

                                @vernes
                                One point i would like to talk about here.
                                The Software engineering warns to use the minimum coupling while maximize the cohesion of class.

                                Note: Inheritance is a 2 edged weapon, reusability is good but dependence is bad.

                                If you decide to modify a class with a high dependency level, it can break the logic of some dependent class and it can be recursive.

                                V Offline
                                V Offline
                                vernes
                                wrote on last edited by vernes
                                #15

                                @KillerSmath said in Qt signal-slot duplication code avoidance:

                                @vernes
                                One point i would like to talk about here.
                                The Software engineering warns to use the minimum coupling while maximize the cohesion of class.

                                Note: Inheritance is a 2 edged weapon, reusability is good but dependence is bad.

                                If you decide to modify a class with a high dependency level, it can break the logic of some dependent class and it can be recursive.

                                Good point here. However I would say that the approach I'm describing is much better compared to a lot of copy & paste.

                                I'd avoid use inheritance but unfortunately Qt seems encouraging it.

                                Problem is Qt and templates do not work well together, and many things like CRTP are not possible in many cases.

                                1 Reply Last reply
                                1

                                • Login

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