当前位置: 首页 > news >正文

Qt中的元对象系统

      Qt的元对象系统(Meta-Object System)提供了对象间通信的信号和槽机制、运行时类型信息和动态属性系统

      元对象系统基于以下三个方面

      (1).QObject类:为可以利用元对象系统的对象提供了基类。

      (2).Q_OBJECT宏:用于启用元对象功能,例如动态属性、信号和槽。Q_OBJECT宏内容如下:

#define Q_OBJECT \
public: \
    QT_WARNING_PUSH \
    Q_OBJECT_NO_OVERRIDE_WARNING \
    static const QMetaObject staticMetaObject; \
    virtual const QMetaObject *metaObject() const; \
    virtual void *qt_metacast(const char *); \
    virtual int qt_metacall(QMetaObject::Call, int, void **); \
    QT_TR_FUNCTIONS \
private: \
    Q_OBJECT_NO_ATTRIBUTES_WARNING \
    Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
    QT_WARNING_POP \
    struct QPrivateSignal { explicit QPrivateSignal() = default; }; \
    QT_ANNOTATE_CLASS(qt_qobject, "")

      (3).元对象编译器(Meta-Object Compiler, MOC):为每个QObject子类提供实现元对象功能所需的代码

      MOC工具读取(reads) C++源文件。如果它发现一个或多个包含Q_OBJECT宏的类声明,它会生成另一个C++源文件,其中包含每个类的元对象代码(meta-object code)。生成的源文件要么被 #include到类的源文件中,要么更常见的是,被编译并与类的实现链接。

      通过MOC工具由mainwindow.h生成moc_mainwindow.cpp,内容类似如下图所示:信号函数的实现也在此文件中生成此.cpp文件对应的CMake命令为qt6_wrap_cpp

      元对象代码除了提供对象间通信的信号和槽机制(引入该系统的主要原因)外,还提供以下附加功能

      (1).QObject::metaObject():返回与该类相关的元对象。

      (2).QMetaObject::className():在运行时以字符串形式返回类名,无需通过C++编译器支持本机运行时类型信息(run-time type information, RTTI)。

      (3).QObject::inherits():函数返回某个对象是否是继承QObject继承树中指定类的类的实例。

      (4).QObject::tr():翻译字符串以实现国际化(internationalization)。

      (5).QObject::setProperty():通过名称动态设置属性。

      (6).QObject::property():通过名称动态获取属性。

      (7).QMetaObject::newInstance():构造该类新实例。

      qobject_cast():可以使用qobject_cast()对QObject类执行动态转换。qobject_cast()函数的行为类似于标准C++ dynamic_cast(),其优点是它不需要RTTI支持,并且可以跨动态库边界(dynamic library boundaries)工作。它尝试将其参数转换为尖括号中指定的指针类型,如果对象是正确的类型(在运行时确定),则返回非零指针,如果对象的类型不兼容,则返回nullptr。

      虽然可以使用QObject作为基类,而无需Q_OBJECT宏和元对象代码,但如果不使用Q_OBJECT宏,则信号和槽以及上面描述的其他功能都将不可用。从元对象系统的角度来看,没有元代码的QObject子类相当于其具有元对象代码的最近祖先(closest ancestor)。这意味着,例如,QMetaObject::className()将不会返回你的类的实际名称,而是返回此祖先的类名。

      强烈建议QObject的所有子类都使用Q_OBJECT宏,无论它们是否实际使用信号、槽和属性

      QMetaObject类:包含有关Qt对象的元信息(meta-information)。

      (1).Qt中的元对象系统负责信号和槽对象间通信机制、运行时类型信息和Qt属性系统。为应用程序中使用的每个QObject子类创建一个QMetaObject实例,此实例存储 QObject子类的所有元信息。此对象可用作QObject::metaObject()。

      (2).此类通常不是应用程序编程所必需的,但如果你编写元应用程序(例如脚本引擎或GUI构建器),它会很有用。

      (3).使用元对象系统的操作通常是线程安全的,因为QMetaObjects通常是编译时生成的静态只读实例(static read-only instances)。但是,如果应用程序动态修改元对象(例如,使用QQmlPropertyMap时),则应用程序必须明确同步对相应元对象的访问。

      注:以上整理的内容主要来自于Qt官方文档

      GitHub:https://github.com/fengbingchun/Qt_Test

相关文章:

  • 基于chatgpt得到的生活成本计算
  • 开源免费虚拟化软件PVE功能介绍
  • 服务器报错:xxx/libc.so.6: version `GLIBC_2.32‘ not found
  • 软件工程第二章
  • STM32 基础2
  • 华为交换机上配置流量策略根据IP限速
  • CentOS安装Docker
  • 005 vue项目结构 vue请求页面执行流程(vue2)
  • Spring IoCDI
  • tomcat的负载均衡和会话保持
  • 微信小程序生成某个具体页面的二维码
  • JVM基础架构:内存模型×Class文件结构×核心原理剖析
  • 算法刷题记录——LeetCode篇(2.6) [第151~160题](持续更新)
  • 使用ExcelJS实现专业级医疗数据导出功能:从数据到Excel报表的完整指南
  • vscode调试vite项目断点(debugger)
  • 基于HAI应用,从零开始的NLP处理实践指南
  • 【区块链安全 | 第三十一篇】合约(五)
  • CVAT及其半自动标注安装(Windows)
  • SYN Flooding攻击原理
  • OpenCV--图像形态学
  • 大学2025丨北大教授陈平原:当卷不过AI时,何处是归途
  • 蒲慕明院士:好的科普应以“质疑、讨论公众关切的科学问题”为切入点
  • 蔡建忠已任昆山市副市长、市公安局局长
  • 南京艺术学院博导、雕塑家尹悟铭病逝,年仅45岁
  • 新城市志|GDP万亿城市,一季度如何挑大梁
  • 美联储官员:美国经济增速可能放缓,现行关税政策仍将导致物价上涨