0
点赞
收藏
分享

微信扫一扫

Qt之使用invokeMethod异步调用函数


在主线程中如果执行比较耗时的任务,但是又不想单独开子线程来处理,不妨试试Qt中提供QMetaObject::invokeMethod方法,该方法支持函数的异步调用,这样就会在界面显示后去执行,而不会卡主主界面

QMetaObject::invokeMethod(this, "MyMethod", Qt::QueuedConnection);

这里MyMethod就是被调用的函数名,如果MyMethod带参数且有返回值,如下所示

QString retVal;
QMetaObject::invokeMethod(obj, "MyMethod", Qt::DirectConnection,
Q_RETURN_ARG(QString, retVal),
Q_ARG(QString, "sqrt"),
Q_ARG(int, 42),
Q_ARG(double, 9.7));

需要注意的是,如果第三个参数使用Qt::QueuedConnection,即异步调用,将无法获取返回值,因为此连接方式只是负责把事件交给事件队列,然后立刻返回,所以函数返回值就无法确定了
invokeMethod函数原型

bool QMetaObject::invokeMethod(QObject *obj, const char *member, 
Qt::ConnectionType type,
QGenericReturnArgument ret,
QGenericArgument val0 = QGenericArgument(nullptr),
QGenericArgument val1 = QGenericArgument(nullptr),
................................................);

此函数用于调用对象的成员(信号或插槽)。如果可以调用成员,则返回true。如果没有此类成员或参数不匹配,则返回false。
参数说明:
obj:被调用对象的指针
member:成员方法的名称
type:连接方式,默认值为 Qt::AutoConnection
Qt::DirectConnection,则会立即调用该成员。(同步调用)
Qt::QueuedConnection,则会发送一个QEvent,并在应用程序进入主事件循环后立即调用该成员。(异步调用)
Qt::BlockingQueuedConnection,则将以与Qt :: QueuedConnection相同的方式调用该方法,除了当前线程将阻塞直到事件被传递。使用此连接类型在同一线程中的对象之间进行通信将导致死锁。(异步调用)
Qt::AutoConnection,则如果obj与调用者位于同一个线程中,则会同步调用该成员; 否则它将异步调用该成员
更详细的介绍参考Qt Assistant
当函数的参数有自定义类型时,需要用qRegisterMetaType()来注册自定义类型,否则会报错

#include <QMetaType>
struct MyData{
int aa,
bool bb
};
qRegisterMetaType<MyData>("MyData");
// 此时的MyMethod没有返回值.
// 因为默认使用的连接方式是Qt::AutoConnection,所以连接方式也可以不指定.
QMetaObject::invokeMethod(this, "MyMethod", Q_ARG(MyData, data)

举报

相关推荐

0 条评论