Amy
Amy

Reputation: 1904

How to get a return value from QMetaObject::invokeMethod

I am calling from my thread the following:

QMetaObject::invokeMethod(pProcessor,
                          "doTask",
                          Qt::QueuedConnection,
                          Q_RETURN_ARG(quint32, taskId),
                          Q_ARG(quint64,   objId),
                          Q_ARG(quint8,    intId),
                          Q_ARG(QString,   name),
                          Q_ARG(QString,   comment)
                          );

but it just fails, no matter what I do. If I take out Q_RETURN_ARG(quint32, taskId), the method is invoked, but I need the taskId, which I cannot get. Any help is much appreciated.

Upvotes: 16

Views: 13390

Answers (3)

Arunprasad Rajkumar
Arunprasad Rajkumar

Reputation: 1444

I'm assuming you want to call a method of an object from non owner thread & wants to get the return value. In order to do that use "Qt::BlockingQueuedConnection" as a connection type.

quint32 taskId; // Declare taskId.
qRegisterMetaType<quint32>("quint32");
QMetaObject::invokeMethod(pProcessor,
                      "doTask",
                      Qt::BlockingQueuedConnection,
                      Q_RETURN_ARG(quint32, taskId),
                      Q_ARG(quint64,   objId),
                      Q_ARG(quint8,    intId),
                      Q_ARG(QString,   name),
                      Q_ARG(QString,   comment)
                      );

Incase your method returns non standard return type you have to register your type before calling QMetaObject::invokeMethod(...). Refer http://qt-project.org/doc/qt-5.0/qtcore/qmetatype.html#qRegisterMetaType.

Upvotes: 31

CapelliC
CapelliC

Reputation: 60024

from docs: If the invocation is asynchronous, the return value cannot be evaluated.

Then you should switch to Qt::DirectConnection, or change your design. QFuture, of course, could help.

I blogged here about a different solution, using C++ lambda facility to issue calls from background threads to GUI thread (see the text after 'My Solution' label).

Upvotes: 0

Oleg Pyzhcov
Oleg Pyzhcov

Reputation: 7353

The documentation for invokeMethod states that

The return value of the member function call is placed in ret. If the invocation is asynchronous, the return value cannot be evaluated.

I guess this happens because the code below this function call is continued to be executed, while your doTask method may not yet be called. Try using Qt::DirectConnection therefore.

Upvotes: 1

Related Questions