PDA

View Full Version : invoke methods in another thread and get return values



elk
9th February 2011, 12:02
Hello!

Suppose a class (derived from QObject) with methods such as

int receiveValue()

The class' events are processed in QThread. There are methods without returning value which may be called asynchronous. The values are needed to be given in similar way as using explicit method invocation but must not be running in caller thread.

It is unable to QMetaObject::invokeMethod with return values in queued connections. The only solution I found is declare methods like

void receiveValue(int *ret)
and invoke methods in Qt::BlockingQueuedConnection. But it is not so beautiful.

Is there another solution alike QMetaObject::invokeMethod(), but with return values and queued connections?

In addition to aesthetic, I have an academic interest in this problem.

high_flyer
9th February 2011, 12:15
Just to be clear I understand:
Are you looking for signals/slots with return values other than void, is that it?

elk
9th February 2011, 12:49
Yes, it's the slots returning values.

high_flyer
9th February 2011, 13:08
I can't test at the moment, but its possible that slots actually can be defined with a return value - however, when used as a slot, how do you want to get the value?
Since you are not calling the slot directly, but only invoke its call (as in emit a signal), and not by the object invoking emitting the signal - so what good would it be for you if the slot is retuning a value - you can't get to that value any way (in the object that emitted the signal)!
Or in other words, you can get the return value only there where the slot is really called - namely in the MetaObject but there you probably wont know what to do with the return value...

Try defining a slot that returns a value and see if the connection works.
If it does, you are still stuck with my question - when and how do you want to get the return value from the slot?

stampede
9th February 2011, 13:21
Have you seen QFuture (http://doc.qt.nokia.com/4.7-snapshot/qfuture.html) and QtConcurrent (http://doc.qt.nokia.com/4.7-snapshot/qtconcurrentrun.html#run) ?
This does exactly what you ask in the thread title.

elk
9th February 2011, 13:37
If it does, you are still stuck with my question - when and how do you want to get the return value from the slot?

As I did say, I use QMetaObject::invokeMethod().
It is possible to get return value (see Q_RETURN_ARG macro), but only in Qt::DirectConnection, i.e. slot will be running in the same thread as a caller object. But I need it running in another thread. It can be achieved only in queued connection, in this case invokeMethod() with the Q_RETURN_ARG is useless. But I can write some data in memory passing its pointer as a slot argument (using Qt::BlockingQueuedConnection, of course). But I thought there is another way similar to invokeMethod() with Q_RETURN_ARG.

int someValue() is more beautiful than void giveMeSomeValue(int *where).

Added after 11 minutes:


This does exactly what you ask in the thread title.

Can I select a particular QThread from global pool?

stampede
9th February 2011, 14:51
Try defining a slot that returns a value and see if the connection works.
Yes, connection to a slot returning value works ok.

Can I select a particular QThread from global pool?
I don't know, why do you need a particular thread to run your code ?

elk
9th February 2011, 16:00
I don't know, why do you need a particular thread to run your code ?

Because that code interacts with a network (QTcpSocket)

wysota
9th February 2011, 16:11
You can send (not post!) an event to an object living in another thread. The event will be handled and if you provide a placeholder for the result in the event object you can then retrieve it in the code that sent the event.

By the way, I don't see anything in Qt code that would technically prevent blocking-queued semantics from providing a return value so you might post a suggestion on Qt's bugtracker that such a situation should be allowed.

MarekR22
10th February 2011, 13:45
Isn't easer (to code and to maintain) make slot to emit a signal with a result?
Then receiving a result from another thread would be quite simple.

wysota
10th February 2011, 20:45
It is technically possible but it is against most object oriented programming rules.