Qt signal-slot duplication code avoidance
-
wrote on 2 May 2019, 10:15 last edited by vernes 5 Feb 2019, 10:28
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
-
wrote on 2 May 2019, 10:29 last edited by
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 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
-
wrote on 2 May 2019, 10:41 last edited by
@CP71 said in Qt signal-slot duplication code avoidance:
@vernes
Hi,
I think in CommonSignals you lost Q_OBJECT macroYep, it's just pseudocode, just to give you an idea
-
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...wrote on 2 May 2019, 10:45 last edited by@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 -
@CP71 said in Qt signal-slot duplication code avoidance:
@vernes
Hi,
I think in CommonSignals you lost Q_OBJECT macroYep, it's just pseudocode, just to give you an idea
wrote on 2 May 2019, 10:53 last edited by KillerSmath 5 Feb 2019, 10:54 -
@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 problemswrote on 2 May 2019, 11:06 last edited by@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 -
wrote on 2 May 2019, 11:07 last edited by
@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?
-
@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 classeswrote on 2 May 2019, 11:12 last edited by@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 classesIt 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.
-
@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 classesIt 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.
wrote on 2 May 2019, 11:19 last edited byYou 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 };
-
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 };
wrote on 2 May 2019, 11:57 last edited by@KillerSmath said in Qt signal-slot duplication code avoidance:
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 :)
-
@CP71 said in Qt signal-slot duplication code avoidance:
@vernes
Hi,
I think in CommonSignals you lost Q_OBJECT macroYep, it's just pseudocode, just to give you an idea
wrote on 3 May 2019, 09:09 last edited by@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_OBJECTpublic:
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 -
wrote on 3 May 2019, 10:32 last edited by vernes 5 Mar 2019, 10:33
@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.
-
@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.
wrote on 3 May 2019, 13:06 last edited by@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.
-
@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.
wrote on 3 May 2019, 16:04 last edited by vernes 5 Mar 2019, 16:06@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/15