如果用QT书写GUI的话,为不影响主界面的工作(不卡主界面),实现工作线程和GUI线程的调度,QT提供了很好的方法——QMetaObject::invokeMethod,并针对该函数提供了多个重载。本文将常用功能记录如下。
在客户端编程中,尤其是针对复杂的客户端场景下,尤其是GUI和工作线程之间需要交互时,经常涉及到异步到同步之间的转换,包括但不限于如下的场景:
http请求
websocket请求
调用第三方sdk时,第三方返回给出的回调需要GUI响应
如果用QT书写GUI的话,QT提供了很好的方法——QMetaObject::invokeMethod,并针对该函数提供了多个重载,如下
[static] bool QMetaObject::invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret,
QGenericArgument val0 = QGenericArgument(nullptr),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument(),
QGenericArgument val9 = QGenericArgument())
参数详解
该函数提供了多个版本的重载,如
输入参数忽略连接类型,为Qt::AutoConnection
bool QMetaObject::invokeMethod(QObject *obj, const char *member,
QGenericReturnArgument ret,
QGenericArgument val0 = ...,
QGenericArgument val1 = ...,
QGenericArgument val2 = ...,
QGenericArgument val3 = ...,
QGenericArgument val4 = ...,
QGenericArgument val5 = ...,
QGenericArgument val6 = ...,
QGenericArgument val7 = ...,
QGenericArgument val8 = ...,
QGenericArgument val9 = ...)
不关心被调用函数的返回值
[static] bool QMetaObject::invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type,
QGenericArgument val0 = ...,
QGenericArgument val1 = ...,
QGenericArgument val2 = ...,
QGenericArgument val3 = ...,
QGenericArgument val4 = ...,
QGenericArgument val5 = ...,
QGenericArgument val6 = ...,
QGenericArgument val7 = ...,
QGenericArgument val8 = ...,
QGenericArgument val9 = ...)
既采用默认连接方式也不关心返回值
[static] bool QMetaObject::invokeMethod(QObject *obj, const char *member,
QGenericArgument val0 = ...,
QGenericArgument val1 = ...,
QGenericArgument val2 = ...,
QGenericArgument val3 = ...,
QGenericArgument val4 = ...,
QGenericArgument val5 = ...,
QGenericArgument val6 = ...,
QGenericArgument val7 = ...,
QGenericArgument val8 = ...,
QGenericArgument val9 = ...)
只要掌握了第一种(最复杂的那种)情况,其余的也就掌握了。
QMetaObject::invokeMethod(this, [this, name, level]()
{
updateLevels(name.toUtf8().data(), level, 0, 0);
}, Qt::QueuedConnection);//不关心返回值也无需输入参数
if(QMetaObject::invokeMethod(m_pOne, "slotAdd",
Qt::AutoConnection,
QGenericReturnArgument("int", poutput)//poutput为指针
,Q_ARG(int, 5),
Q_ARG(int, 6)
))
{
qDebug()<<"integer"<
//m_pOne为被连接的对象,
//add为被连接的函数,实现加和计算
int re;
if(QMetaObject::invokeMethod(m_pOne, "add",
Qt::AutoConnection,
Q_RETURN_ARG(int, re)//re需提前定义
,Q_ARG(int, 7),
Q_ARG(int, 8)
))
{
qDebug()<