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
Forum Updated to NodeBB v4.3 + New Features

Qt signal-slot duplication code avoidance

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 4 Posters 1.3k 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.
  • 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