Connecting to signal of another class
-
Hello, I am attempting to connect a signal from one class instance to another but am having trouble.
Here is the scenario. I have 3 classes, ClassA, ClassB and ClassC. ClassA inherits ClassB, ClassB inherits QObject, and ClassC inherits QObject.
The idea is that I will create potentially multiple instances of ClassA, whose inherited class B instance needs to receive signals from the same single instance of ClassC. ClassA registers a pointer to the ClassC instance upon creation, and ClassB will use that to connect to the signal.
However, this method is crashing upon invoking connect in the constructor of Class B. I get a seg fault, which is probably because of some type of null pointer, but I can't tell exactly. See code below:
// classa.cpp #include <classa.h> ClassA::ClassA(ClassC * somecclass) { classc = somecclass; } // classa.h #ifndef CLASSA_H #define CLASSA_H #include <classb.h> #include <classc.h> #include <QObject> class ClassA: ClassB { Q_OBJECT public: ClassA(ClassC * somecclass); }; #endif // CLASSA_H // classb.cpp #include "classb.h" ClassB::ClassB() { // Crash happens here connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot())); } void ClassB::classBslot(void) { } // classb.h #ifndef CLASSB_H #define CLASSB_H #include <QObject> #include <classc.h> class ClassB : public QObject { Q_OBJECT public: ClassB(); ClassC * classc; signals: public slots: void classBslot(void); }; #endif // CLASSB_H // classc.cpp #include "classc.h" ClassC::ClassC() { } // classc.h #ifndef CLASSC_H #define CLASSC_H #include <QObject> class ClassC : public QObject { Q_OBJECT public: ClassC(); signals: void classCsignal(); public slots: }; #endif // CLASSC_H // main.cpp ClassC classc; ClassA classa(&classc); // loop and do other stuff
If however in ClassB, instead of having a pointer, I create a local instance of ClassC and then use this in connect, it works. Why can't I do the original way? Is there some weird order of QObject initialization where the signals aren't there yet or something, or am I missing something else? I'm simply use a pointer to an outside already initialize outside instance of a class vs. a local instance.
Thanks
-
Hi,
Looks like your
classC
object is not initialised before you use it. -
Hi
That should work fine as longs ClassC classc; stays in scope.
So i would check my cached pointerin .h
ClassC * classc=nullptr;and
ClassB::ClassB() // it has no parameter here of type ClassC ???? so where do you store it ?
{
// Crash happens here
if (!classc )
qDebug() << "ptr is null";
else
connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot()));
} -
@SGaist said in Connecting to signal of another class:
Hi,
Looks like your
classC
object is not initialised before you use it.What do you mean? I create an instance of it in main before creating a ClassB instance.
@mrjj said in Connecting to signal of another class:
Hi
That should work fine as longs ClassC classc; stays in scope.
So i would check my cached pointerin .h
ClassC * classc=nullptr;and
ClassB::ClassB() // it has no parameter here of type ClassC ???? so where do you store it ?
{
// Crash happens here
if (!classc )
qDebug() << "ptr is null";
else
connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot()));
}I verified that classc is not a NULL pointer.
The ClassC pointer is indeed stored in the ClassB instance:
// classb.h public: ClassB(); ClassC * classc;
This should not go out of scope because main never returns. Also, I verified that if I do this same exact method, but instead call connect in a separate function call, it works fine. It seems that this just doesn't work when called from the constructor.
-
So
the real code looks like
ClassB(ClassC *theptr) : classc(theptr ) {connect(classc, xxxx )
}?
-
@mrjj said in Connecting to signal of another class:
So
the real code looks like
ClassB(ClassC *theptr) : classc(theptr ) {connect(classc, xxxx )
}?
No ClassB doesn't inherit ClassC. There's simply a static ClassC * pointer called "classc" in ClassB. This holds a reference to an instance of ClassC .
The reason for doing it this way, is there will be a single instance of ClassC, which ClassA/(and inherited ClassB) need to all reference.
i.e.
ClassC globalCinstance; ClassA classAinstance1(&globalCinstance); ClassA classAinstance2(&globalCinstance); ClassA classAinstance3(&globalCinstance);
What I was saying that does work, is doing something like this:
// main.cpp ClassC someclassC; ClassA someclassA; someclassA.registerSignal();
where
// classb.cpp void ClassB::registerSignal() { connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot())); }
and even this works too:
// main.cpp ClassC someclassC; ClassA someclassA; // classa.cpp ClassA::ClassA(ClassC * somecclass) { classc = somecclass; // Call registerSignal from inherited ClassB registerSignal(); } // classb.cpp void ClassB::registerSignal() { connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot())); }
It seems that it just can't be called from the constructor of ClassB
-
@kengineer said in Connecting to signal of another class:
connect(classc, SIGNAL(classCsignal()), this, SLOT(classBslot()));
You may want to use signals and slots new syntax as it provides information at compile time which may shed some light about your issue