[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



  • 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.



  • I find your code sample hard to understand, and I can't figure out what's going on. Could you create something that looks a bit more like I could compile it and that is closer your actual code?



  • 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.

    1. the QML page has an instance of registered Cpp class and a mouse area.
    2. whenever user clicks in mouse area, from onClicked slot, request is made by calling Q_INVOKABLE function of registered Cpp class.
    3. Q_INVOKABLE function simply enqueues the request in Qqueue.
    4. whenever there is a request available, thread of slot class fetches request and creates instance of signal class.
    5. signal class will does some operation and on completion emits signal to slot class.

    now the slot is not executed upon emission.



  • I was asking for code to look at, not a description.
    I am wondering how you notify your thread that there is something to pick out the queue though. Not a constant polling, I hope? Are you sure that that actually happens?



  • @ Andre...
    Sorry, I didn't see your post, and wrote that details for Gerolf...
    Anyways, It's an official project so I am not allowed to paste my code here. So i can write a sample code similar to it and then post it here later.



  • [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 &#40;&#41;;
    

    }
    @

    Parent.h
    @
    #ifndef PARENT_H
    #define PARENT_H

    #include <QThread>
    #include "Child.h"

    class Parent : public QThread
    {
    Q_OBJECT

    public:
    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_OBJECT

    public:
    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 () &lt;&lt; "Child::SlotChild"
              << "Emitting signal";
    
    emit SigChild (objectPtr);
    

    }
    @

    GrandChild.h
    @
    #ifndef GRANDCHILD_H
    #define GRANDCHILD_H

    #include <QThread>

    class GrandChild : public QThread
    {
    Q_OBJECT

    public:
    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].???



  • You Are Doing It Wrong (TM).

    Google for it.



  • 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.???

    1. to subclass QThread class and write functionality into run () .???
      or
    2. 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



  • "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...



  • Sorry, I don't have time (nor want to spend to time) at dissecting code that is inherently wrong anyway.



  • 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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.