概述

Qt元对象系统是Qt最核心的一个基础特性,元对象系统负责信号和插槽对象间通信机制、运行时类型信息和Qt属性系统。为应用程序中使用的每个QObject子类创建一个QMetaObject实例,此实例存储QObject子类的所有元信息。通过元对象系统,你可以查询QObject的某个派生类的类名、有哪些信号、槽、属性、可调用方法等信息,然后可以使用QMetaObject::invokeMethod()调用QObject的某个注册到元对象系统中的方法。而这里,主要就介绍改函数的使用方法,以及大致简介。

QMetaObject::invokeMethod()

QMetaObject的invokeMethod()方法用来调用一个对象的信号、槽、可调用的方法。这是一个静态方法,其函数原型如下:

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

在最新的Qt5.13中,QMetaObject中的invokeMethod函数一共有五个,除上面这个以外其他都是重载函数,就不一一介绍。

该函数就是调用obj对象中的member方法,如果调用成功则返回true,调用失败则返回false,失败的话要么就是没有这个方法要么就是参数传入不对。

参数介绍

  • 第一个参数是被调用对象的指针;
  • 第二个参数是方法的名字;
  • 第三个参数是连接类型。可以指定连接类型,来决定是同步还是异步调用。
    • 如果type是Qt :: DirectConnection,则会立即调用该成员。
    • 如果type是Qt :: QueuedConnection,则会发送一个QEvent,并在应用程序进入主事件循环后立即调用该成员。
    • 如果type是Qt :: BlockingQueuedConnection,则将以与Qt :: QueuedConnection相同的方式调用该方法,除了当前线程将阻塞直到事件被传递。使用此连接类型在同一线程中的对象之间进行通信将导致死锁。
    • 如果type是Qt :: AutoConnection,则如果obj与调用者位于同一个线程中,则会同步调用该成员; 否则它将异步调用该成员。
  • 第四个参数接收被调用函数的返回值;注意,如果调用是异步的,则无法计算返回值。

注意:传入的参数是有个数限制的,可以向成员函数传递最多十个参数(val0,val1,val2,val3,val4,val5,val6,val7,val8和val9)。

QGenericArgument和QGenericReturnArgument是内部帮助程序类。由于可以动态调用信号和槽,因此必须使用Q_ARG()和Q_RETURN_ARG()宏来封装参数。Q_ARG()接受该类型的类型名称和const引用; Q_RETURN_ARG()接受类型名称和非const引用。

注意:此功能是线程安全的。

调用示例

假设一个对象有一个槽compute(QString,int,double),返回一个QString对象,那么调用方式如下(同步):

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

假设要异步调用QThread上的quit()槽:

QMetaObject::invokeMethod(thread, "quit", Qt::QueuedConnection);

注意,要调用的类型必须是信号、槽,以及Qt元对象系统能识别的类型, 如果不是信号和槽,可以使用qRegisterMetaType()来注册数据类型。此外,使用Q_INVOKABLE来声明函数,也可以正确调用。

Qt之QMetaObject::invokeMethod()使用简介相关推荐

  1. Qt发展历史及其特点简介

    Qt 是一个跨平台的C++应用程序框架,支持Windows.Linux.Mac OS X.Android.iOS.Windows Phone.嵌入式系统等.也就是说,Qt 可以同时支持桌面应用程序开发 ...

  2. Qt音视频开发01-共享解码线程(耗时一年/性能凶残/至臻完美)

    一.前言 大概在8年前就开始用ffmpeg做视频解码的显示,第一个版本就100行代码左右,功能极其简单,就是开个线程解码视频流转成图片发给主界面绘制.时间过得真快,从当初的一胎到现在二胎都上学了三胎计 ...

  3. 简单说说对QT中moveToThread实现多线程操作的理解

      在平时的编码过程中经常碰到QT的多线程问题,也大量接触了QT中的两种主流多线程写法,一种是继承QThread类并重载run函数,在run函数中写一个状态机或者计时器来实现对线程运作:一种是通过mo ...

  4. rk3399视频显示_二

    本篇主要讲解怎么处理ffmpeg读取视频的packet包 视频显示的步骤,读流-解码-显示三部分.AVPacket我们并不能直接使用,需要进行解码后才可以.解码分为软解和硬解,前者兼容性强,但是耗cp ...

  5. 万字长文系统梳理C++函数指针

    本篇的内容相对比较简单 主要从语法的层面讲解函数指针的使用以及应用场景.都是些面向入门者的基础,大佬轻喷. 首先:什么是函数指针. 这个问题老生常谈了,不用理解的多么复杂,它其实就是一个特殊的指针,它 ...

  6. Qt使用invokeMethod反射机制实现进程间的通信

    对于Qt来说,UI线程是主线程,对于同一UI线程中对象的通信可以通过connect进行信号与槽关联来实现,但是当UI中对象A中的子线程B需要和另外UI对象C进行通信的时候,如果这个时候使用connec ...

  7. Qt元对象系统:QMetaObject

    一.描述 此类包含有关Qt对象的元信息.Qt为应用程序中使用的每个 QObject 子类创建一个 QMetaObject 实例,该实例存储 QObject 子类的所有元信息. 二.静态成员函数 1.Q ...

  8. 6、Qt Meta Object system 学习

    原文地址:http://blog.csdn.net/ilvu999/article/details/8049908 使用 meta object system 继承自 QOject 类定义中添加 Q_ ...

  9. Qt Quick 之 QML 与 C++ 混合编程详解

    Qt Quick 技术的引入,使得你能够快速构建 UI ,具有动画.各种绚丽效果的 UI 都不在话下.但它不是万能的,也有很多局限性,原来 Qt 的一些技术,比如低阶的网络编程如 QTcpSocket ...

最新文章

  1. CVPR2020检测类论文最全汇总:136篇论文方向细分(附代码和论文打包下载)
  2. ali arthas 火焰图_带你上手阿里开源的 Java 诊断利器:Arthas
  3. Python之路【第八篇】python实现线程池
  4. 基于ArcGIS JS API 的点击查询功能
  5. js-权威指南学习笔记7
  6. JAVA知识基础(七):封装
  7. xp无法使用计算机管理员权限,xp无法无法使用管理员权限运行软件的解决步骤...
  8. Android Shape工具 Duck
  9. POJ 2287 田忌赛马 贪心算法
  10. SQL多表合并查询结果
  11. 安全标准ISO 17799/27001
  12. 启动Kylin出现的问题
  13. 基于android的校园新闻app,移动端校园新闻APP的设计探析
  14. stable diffusion制作韩国版AI女友关键词
  15. Pytorch CPU Tensor与GPU Tensor的运算速度对比测试
  16. 转:史上最强《软件工程师面试题》答案
  17. SQL文件的导入与导出
  18. 9个网站,给不知道去哪找数据的你
  19. UE4-LOD理解-Distance culling(距离剔除体积)和Visibility culling(可视化剔除体积)
  20. 一个网站服务器需要多大带宽,网站需要多大的带宽 ?

热门文章

  1. VideoLAN、VLC 和 FFmpeg联合开发AV1 解码器 Dav1d
  2. 聊聊网易技术如何帮教育行业开出花
  3. 网易云信欢乐颂(送),领取“五美”送麻麻
  4. linux用户简单指令操作
  5. 正则(身份证,手机号,邮箱,正整数)
  6. js setTimeout 传递带参数的函数的2种方式
  7. 一点一点看JDK源码(四)java.util.ArrayList 中篇
  8. String与Date转换
  9. 「Android」 详细全面的基于vue2.0Weex接入过程(Android视角)
  10. Java反射理解与案例