Как получить возвращаемое значение из QMetaObject:: invokeMethod

Я вызываю из своего потока следующее:

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)
                          );

но он просто терпит неудачу, независимо от того, что я делаю. Если я выберу Q_RETURN_ARG (quint32, taskId), метод будет вызван, но мне нужен taskId, который я не могу получить. Любая помощь очень ценится.

Ответ 1

Я предполагаю, что вы хотите вызвать метод объекта из потока не-владельца и хотите получить возвращаемое значение. Для этого используйте "Qt:: BlockingQueuedConnection" в качестве типа подключения.

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)
                      );

Если ваш метод возвращает нестандартный тип возврата, вам необходимо зарегистрировать свой тип перед вызовом QMetaObject:: invokeMethod (...). Обратитесь http://qt-project.org/doc/qt-5.0/qtcore/qmetatype.html#qRegisterMetaType.

Ответ 2

В документации для invokeMethod указано, что

Возвращаемое значение вызова функции-члена помещается в ret. Если вызов является асинхронным, возвращаемое значение не может быть оценено.

Я предполагаю, что это происходит потому, что код ниже этого вызова функции продолжает выполняться, тогда как ваш метод doTask еще не может быть вызван. Поэтому используйте Qt::DirectConnection.

Ответ 3

из документов: If the invocation is asynchronous, the return value cannot be evaluated.

Затем вы должны переключиться на Qt:: DirectConnection или изменить свой дизайн. QFuture, конечно, может помочь.

Я написал здесь о другом решении, используя средство С++ lambda для вызова вызовов из фоновых потоков в поток графического интерфейса (см. текст после "Мой Solution" ).