[SOLVED] Signal Slot failure...
-
Hello,
I have written a code in which there is an instance of slot class which contains a pointer of signal class and it provides a function to make request.
Whenever I need to do some operation, I call function of slot class in which I create a new instance of signal class and connect signal of signal class to slot of slot class, the return value is true. and I start thread of signal class, which on completion of operation, emits a signal. I expect the connected slot to be called but it doesn't happens.
I even checked the address of slot class and signal class [when created and when signal is emitted] they are ok.so what can be the possible reason for failure.?
steps are as follow,
@
void slot class :: operation function ()
{
loop
if any request is pending
create signal class
connect signal of signal class to slot of slot class.
start signal class thread
else
wait for request signal
endif
endloop
}void slot class :: slot function ()
{}
void signal class :: run ()
{
do some operation
emit signal
}
@EDITED:
FYI, the operation function is thread (run function) of slot class, which runs in a loop and checks a 'request buffer' for any pending request and serves if any. -
Your code looks like if the signal class is a QThread derived class, right?
If yes, then the connect makes a direct connection, as the QThread object belongs to the creating thread.
Have a look at this "wiki page from peppe":http://qt-project.org/wiki/ThreadsEventsQObjects or "this thread":http://qt-project.org/wiki/QThreads_general_usage -
ok, lat me explain in detail.
there is a QML page, one Cpp class which is made visible to QML by qMetaRegister method, one slot class and few signal classes.- the QML page has an instance of registered Cpp class and a mouse area.
- whenever user clicks in mouse area, from onClicked slot, request is made by calling Q_INVOKABLE function of registered Cpp class.
- Q_INVOKABLE function simply enqueues the request in Qqueue.
- whenever there is a request available, thread of slot class fetches request and creates instance of signal class.
- signal class will does some operation and on completion emits signal to slot class.
now the slot is not executed upon emission.
-
[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