Slot with return value called via Signal between differen Threads



  • Hi,
    lets say i have a Class Data:
    @
    class Data public QObject
    {
    public slots:
    QString getName()
    {
    QString sTmp = "My Name is Stiffler";
    return sTmp;
    };
    }
    @

    I have antother Class:
    @
    class A public QObject
    {
    signals:
    QString getNameFromData();
    }
    @

    I connet the Signal "getNameFromData" with the Slot "getName()" from Data.
    @
    //This Code is somewhere in class A
    qDebug() << "Name of Class Data:" << getNameFromData();
    @

    This gives:
    Name of Class Data: "My Name is Stiffler"

    So I thought handling signals and slots with non void return values would be no problem at all.

    But as I moved class Data to another Thread then class A, suddenly the code gives:
    Name of Class Data: ""

    So the Return Value seems like just not received.

    Can someone tell me if this is "normal" QT behaivior? Im I doing or understanding something wrong?



  • Hi,

    you're using signals/slots in a wrong way.

    signals and slots MUST return void.

    to connect signal with slot you must use QObject::connect() function and slots receive signals data through its parameters.

    I suggest to read "here":http://qt-project.org/doc/qt-5/signalsandslots.html before to start write code.



  • Im using the QObject:.connect() function.

    What i just dont understand, why does it work with return values between Objects running in the same thread, and why not between Objects running in different threads.

    I mean if it is forbidden to give signals a return value, it should not be working at all and users should get a message like "Error in Line XX: found signal with non void return value"...

    By the way: I wanted to use signals with return value in a Document-View-Controller based applikation, I wanted to use the Acces-functions from the Document for the stored Data as Slots with return value. So I dont have to handle the Document Object or a pointer to it to any View that needs Data. That works very well, as long as i dont put a Class in another thread.


  • Moderators

    [quote author="mcosta" date="1390322166"]
    signals and slots MUST return void.
    [/quote]

    Thats just NOT true.

    Please try the following example:
    @
    class Test : public QObject
    {
    Q_OBJECT

    public:
    TestClass()
    {
    connect(this, SIGNAL(test()), this, SLOT(onTest()));

         int val = emit test();
         qDebug() << val;
     }
    

    signals:
    int test();

    protected slots:
    int onTest()
    {
    return 10;
    }
    };
    @

    It's basically working, but not practicable for most cases, since it might be possible that a signal is connected to multiple slots. In such case only the last value is returned.


  • Lifetime Qt Champion

    Hi,

    The doc states otherwise at least for "signals":http://qt-project.org/doc/qt-5.0/qtcore/signalsandslots.html#signals , they must use void

    For functions with return values, I think Q_INVOKABLE is better suited


  • Moderators

    at rentner323:

    What happens if you try the following instead:
    @
    QString retVal;
    QMetaObject::invokeMethod(objInAnotherThread, "methodToCall", Qt::BlockingQueuedConnection,
    Q_RETURN_ARG(QString, retVal),
    Q_ARG(type1, val1),
    Q_ARG(type2, val2),
    Q_ARG(type3, val3));
    @

    But only use Qt::BlockingQueuedConnection if the obj to call is really in another thread, otherwise it will cause a deadlock.


  • Moderators

    [quote author="SGaist" date="1390377420"]
    The doc states otherwise at least for "signals":http://qt-project.org/doc/qt-5.0/qtcore/signalsandslots.html#signals , they must use void
    [/quote]
    I know, but it works. Try the example i've posted.
    I think it's for the reason i mentioned, because it doesn't make sense for most cases.
    Or the trolls do not want to support it officially :P

    [quote author="SGaist" date="1390377420"]
    For functions with return values, I think Q_INVOKABLE is better suited[/quote]
    AFAIK there is no difference in the result between Q_SLOTS and Q_INVOKABLE defined methods.
    You can even connect signals to Q_INVOKABLE methods.
    I think the only difference is the type of declarations, where with Q_SLOTS you can declare multiple methods at once and with Q_INVOKABLE single methods.


  • Moderators

    [quote author="rentner323" date="1390376109"]What i just dont understand, why does it work with return values between Objects running in the same thread, and why not between Objects running in different threads.[/quote]Hi rentner323,

    What you are seeing is undefined behaviour. Signals are not designed to give you the slots' return values, and there is no guarantee that your example will behave the same way in future versions of Qt.

    Make sure your code never tries to get the return value of a slot through a signal.

    Anyway, signal+slot connections do behave differently depending on the threads involved. To understand why, see the "ConnectionType documentation":http://doc-snapshot.qt-project.org/qt5-stable/qt.html#ConnectionType-enum.


  • Lifetime Qt Champion

    [quote author="raven-worx" date="1390377835"][quote author="SGaist" date="1390377420"]
    The doc states otherwise at least for "signals":http://qt-project.org/doc/qt-5.0/qtcore/signalsandslots.html#signals , they must use void
    [/quote]
    I know, but it works. Try the example i've posted.
    I think it's for the reason i mentioned, because it doesn't make sense for most cases.
    Or the trolls do not want to support it officially :P
    [/quote]

    I didn't say it wouldn't work, but it's not the "Right thing to do (™)" and I agree with JKSH, it's undefined behavior.

    Don't want to feed the Trolls ? :-D

    Like you said, it's an unusual use case, and it should not be supported, image the multithread nightmare...

    [quote author="raven-worx" date="1390377835"][quote author="SGaist" date="1390377420"]
    For functions with return values, I think Q_INVOKABLE is better suited[/quote]
    AFAIK there is no difference in the result between Q_SLOTS and Q_INVOKABLE defined methods.
    You can even connect signals to Q_INVOKABLE methods.
    I think the only difference is the type of declarations, where with Q_SLOTS you can declare multiple methods at once and with Q_INVOKABLE single methods.[/quote]

    It might be completely cosmetic (I can't tell right now) but I find It more clear/clean code wise both for the user and maintainer of the code.


  • Moderators

    [quote author="raven-worx" date="1390377835"]I think it's for the reason i mentioned, because it doesn't make sense for most cases.
    Or the trolls do not want to support it officially :P[/quote]I'd say that the Trolls don't want to support it BECAUSE it doesn't make sense to support it.

    Off-tangent: Trolltech doesn't exist anymore. What should Qt engineers be called now -- Cutes? ;)

    [quote author="SGaist" date="1390427357"]
    [quote author="raven-worx" date="1390377835"]AFAIK there is no difference in the result between Q_SLOTS and Q_INVOKABLE defined methods.
    You can even connect signals to Q_INVOKABLE methods.
    I think the only difference is the type of declarations, where with Q_SLOTS you can declare multiple methods at once and with Q_INVOKABLE single methods.[/quote]

    It might be completely cosmetic (I can't tell right now) but I find It more clear/clean code wise both for the user and maintainer of the code.[/quote]Signals, slots, and 'Q_INVOKABLE's are all invokable meta-methods. When MOC generates the internal "lookup table":http://woboq.com/blog/how-qt-signals-slots-work.html, it lists the signals first, then the slots, then the 'Q_INVOKABLE's.

    Functionally however, slots and 'Q_INVOKABLE's are treated exactly the same way. (Maybe they were treated differently in the past, but they are the same today)

    I agree with SGaist -- The choice between "slots" and "Q_INVOKABLE" aids readability. "emit" also exists only to aid readability -- your program will work exactly the same if you removed all the "emit"s from your code.


Log in to reply
 

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