[SOLVED] Signal Slot failure...
-
[quote author="aekam" date="1348218940"]hmmm... direct or queued connection, slot should be called upon emission of signal, right.??
I have puyt qDebug prints just before emitting signal and at first step of slot function, but it doen't print anything.[/quote]Yes and no. The problem is, that if the connection is queued and the receive happens in a thread which spins no event loop, nothing will happen. So seeing real code where that happens would help a lot to find the problem.
-
Main.cpp
@
#include <QCoreApplication>
#include <QDebug>
#include "Parent.h"int main(int argc, char *argv[])
{
QCoreApplication core (argc, argv);
Parent parent;parent.start (); core.exec ();
}
@Parent.h
@
#ifndef PARENT_H
#define PARENT_H#include <QThread>
#include "Child.h"class Parent : public QThread
{
Q_OBJECTpublic:
Parent ();
~Parent ();
void run ();protected:
Child *child;signals:
void SigParent (QObject *objectPtr);public slots:
void SlotParent (QObject *objectPtr);
};#endif // PARENT_H
@Parent.cpp
@
#include <QDebug>
#include "Parent.h"Parent::Parent ()
{}
Parent::~Parent ()
{}
void Parent::run ()
{
qDebug () << "Parent::run ()"
<< "Thread started";child = new Child (); if (child != NULL) { connect (child, SIGNAL(SigChild(QObject*)), this, SLOT(SlotParent(QObject*))); child->start (); } while (1) sleep (5);
}
void Parent::SlotParent (QObject *objectPtr)
{
qDebug () << "Parent::SlotParent"
<< "Signal received from" << objectPtr;
}
@Child.h
@
#ifndef CHILD_H
#define CHILD_H#include <QThread>
#include "GrandChild.h"class Child : public QThread
{
Q_OBJECTpublic:
Child ();
~Child ();
void run ();protected:
GrandChild *grandChild;signals:
void SigChild (QObject *objectPtr);public slots:
void SlotChild (QObject *objectPtr);
};#endif // CHILD_H
@Child.cpp
@
#include <QDebug>
#include "Child.h"Child::Child ()
{}
Child::~Child ()
{}
void Child::run ()
{
qDebug () << "Child::run ()"
<< "Thread started";grandChild = new GrandChild (); if (grandChild != NULL) { connect (grandChild, SIGNAL(SigGrandChild(QObject*)), this, SLOT(SlotChild(QObject*))); grandChild->start (); } while (1) { sleep (5); qDebug () << "Child::run ()" << "Emitting Signal"; emit SigChild (this); }
}
void Child::SlotChild (QObject *objectPtr)
{
qDebug () << "Child::SlotChild"
<< "Signal received from" << objectPtr;qDebug () << "Child::SlotChild" << "Emitting signal"; emit SigChild (objectPtr);
}
@GrandChild.h
@
#ifndef GRANDCHILD_H
#define GRANDCHILD_H#include <QThread>
class GrandChild : public QThread
{
Q_OBJECTpublic:
GrandChild ();
~GrandChild ();
void run ();signals:
void SigGrandChild (QObject *objectPtr);
};#endif // GRANDCHILD_H
@GrandChild.cpp
@
#include <QDebug>
#include "GrandChild.h"GrandChild::GrandChild ()
{}
GrandChild::~GrandChild ()
{}
void GrandChild::run ()
{
qDebug () << "GrandChild::run ()"
<< "Thread started";
while (1)
{
sleep (5);
qDebug () << "GrandChild::run ()"
<< "Emitting Signal";emit SigGrandChild (this); }
}
@Application Output
Parent::run () Thread started
Child::run () Thread started
GrandChild::run () Thread started
GrandChild::run () Emitting Signal
Child::run () Emitting Signal
Parent::SlotParent Signal received from Child(0xb6e00718)
GrandChild::run () Emitting Signal
Child::run () Emitting Signal
Parent::SlotParent Signal received from Child(0xb6e00718)
GrandChild::run () Emitting Signal
Child::run () Emitting Signal
Parent::SlotParent Signal received from Child(0xb6e00718)
GrandChild::run () Emitting Signal
Child::run () Emitting Signal
Parent::SlotParent Signal received from Child(0xb6e00718)
GrandChild::run () Emitting Signal
Child::run () Emitting Signal
Parent::SlotParent Signal received from Child(0xb6e00718)
GrandChild::run () Emitting Signal
Child::run () Emitting Signal
Parent::SlotParent Signal received from Child(0xb6e00718)
GrandChild::run () Emitting Signal
Child::run () Emitting Signal
Parent::SlotParent Signal received from Child(0xb6e00718)
GrandChild::run () Emitting Signal
Child::run () Emitting Signal
Parent::SlotParent Signal received from Child(0xb6e00718)
and so on...Now the question is, Signal of Child object is received by Parent object, but why the Signal of GrandChild object is not received by Child object [later, if received, relayed to the parent].???
-
Hello Andre, Thank you, you have always been helping... :)
Now I read this, "You're doing it wrong...":http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/ as well this, "Threading without the headache...":http://blog.qt.digia.com/blog/2006/12/04/threading-without-the-headache/...I am confused as some people say that moveToThread shouldn't be used, and some say it's proper way to use it...
Which is the standard way to work with threads.???- to subclass QThread class and write functionality into run () .???
or - to subclass QObject class, write functionality as its APIs and moveToThread object to QThread class object.???
with Qt's documents, I have developed considerable big code and now I am stuck little bit... :P
- to subclass QThread class and write functionality into run () .???
-
"Qt 4.7 QThread":http://qt-project.org/doc/qt-4.7/qthread.html
just checked this online and your comment over there... :) -
Well, I guess you found the answer to your own question there :-)
Note that the recommendation about not using moveToThread is about moving the subclassed QThread instance itself onto it's own thread. Like this:
@// THIS IS * NOT * a good idea:
MyThreadSubclass* thread = new MyThreadSubclass();
thread->moveToThread(thread); // bad, bad, bad
thread->start();@This is a Bad Idea. Instead, move a QObject subclass onto the thread represented by the (vanilla) QThread instance, as in the example in the documentation note you found. The "right" way is also in the "Qt 5 documentation":/doc/qt-5.0/qtcore/qthread.html#details
-
One more question Andre...
In above code,
I connected Child's signal to Parent's slot in run function of Parent. It is working.
I connected GrandChild's signal to Child's slot in run function of Child. It is not working.Why there is difference like, one is working and other is not...
-
It's ok...
being curious, just wanted to know, what exactly is happening...
:)Suppose I need to receive continuous data over TCP [stream from camera].
If I subclass QObject class to provide receiver functionality and make connection between QTcpSocket and QObject class then move this object to QThread.
Wouldn't this lead to frequent signal-slot execution and a busy local event loop.??
Does this affects performance.??
[as signal-slot are slower compare to direct function calls, I think..][Currently I have re-implemented run function to receive stream with QTcpSocket's blocking APIs.]
-
Dear Gerolf and Andre...
Thank you for the links...
They are to the point and very informative.
Solved many of my confusions.
I understood why the things in above code is not working. [and sorry for repeating the same question again n again... :) ]
marking this as solved