invokeMethod
最后更新于:2022-04-02 02:14:10
[TOC]
## invokeMethod
- 如果调用的函数耗时较长,同步调用会造成主程序的堵塞。Qt中提供了一个便捷的函数`QMetaObject::invokeMethod`
- 该函数就是尝试调用obj的member函数,可以是信号、槽或者Q_INVOKABLE声明的函
- QMetaObject::invokeMethod可以是异步调用,也可以是同步调用。这取决与它的连接方式`Qt::ConnectionType`
**函数声明**
```
static bool invokeMethod(QObject *obj, const char *member,
Qt::ConnectionType,
QGenericReturnArgument ret,
QGenericArgument val0 = QGenericArgument(Q_NULLPTR),
...
QGenericArgument val9 = QGenericArgument());
```
**调用方式**
```
enum ConnectionType {
// 则如果obj与调用者位于同一个线程中,则会同步调用该成员; 否则它将异步调用该成员
AutoConnection,
// 则会立即调用该成员。(同步调用)
DirectConnection,
// 则会发送一个QEvent,并在应用程序进入主事件循环后立即调用该成员。(异步调用)
QueuedConnection,
// 则将以与Qt :: QueuedConnection相同的方式调用该方法,除了当前线程将阻塞直到事件被传递。使用此连接类型在同一线程中的对象之间进行通信将导致死锁。(异步调用)
BlockingQueuedConnection,
UniqueConnection = 0x80
};
```
## 声明为 Q_INVOKABLE
```
Q_INVOKABLE void setText(QString msg);
```
## 异步调用注意
当函数的参数有自定义类型时,程序将会报错,因为调用的类型必须是信号、槽,以及Qt元对象系统能识别的类型。可以使用Qt命名类型所提供的`qRegisterMetaType()`来注册自定义类型
```
//头文件
#include
//自定义类型
struct AsynResults {
int imgId;
QImage image;
int result;
};
//在类构造时,注册类型
qRegisterMetaType("AsynResults");
//QMetaObject::invokeMethod调用
QMetaObject::invokeMethod(this, "reportImageResultAsync",
Q_ARG(AsynResults, asynresults);
```
## 实例
```
bool result;
//同步调用
QMetaObject::invokeMethod(obj, "func", Qt::DirectConnection,
Q_RETURN_ARG(bool, result),
Q_ARG(QString, "test"),
Q_ARG(int, 100);
//异步调用
QMetaObject::invokeMethod(obj, "func", Qt::QueuedConnection,
Q_ARG(QString, "test"),
Q_ARG(int, 100);
```
';