(转自:http://blog.csdn.net/aladdina/article/details/5496891)

Qt的元对象系统基于如下三件事情:

  1. 类:QObject,为所有需要利用原对象系统的对象提供了一个基类。
  2. 宏:Q_OBJECT,通常可以声明在类的私有段中,让该类可以使用元对象对象的特性,比如动态属性,信号和槽。
  3. 编译器:元对象编译器(moc)为每个QObject子对象自动生成必要的代码来实现元对象特性。

moc工具会读入C++的源文件,如果它发现了一个或者多个声明了Q_OBJECT宏的类,它就创建另一个C++源文件,为每个类生成包含元对象实现的代码。这些编译生成的源文件通常都已经被包含到类的源文件中或者和类的实现同时被编译和链接。

除了为对象间的通信提供信号和槽(signals and slots)机制之外,元对象的代码还提供下列特性:

  • QObject::metaObject()返回与该类绑定的meta-object对象。
  • QMetaObject::className()可以在运行时以字符串的形式返回类的名字,不需要C++编译器原生的运行时类型信息(RTTI)的支持。
  • QObject::inherits()函数返回继承信息:对象是否是QObject继承树上一个类的实例。
  • QObject::tr()和QObject::trUtf8()提供国际化支持,将字符串翻译成指定的语言。
  • QObject::setProperty()和QObject::property()通过名字动态设置和获取对象属性。
  • QMetaObject::newInstance()构造该类的一个新实例。

除此之外你还可以用qobject_cast()动态转换QObject类的类型。qobject_cast()函数和标准C++的dynamic_cast()功能类似,只是其不需要RTTI的支持,而且可以跨越动态连接库的边界。它尝试将它的参数cast成尖括号内的对象类型,如果对象是正确的类型(运行时决定)则返回非零,否则返回0,说明对象类型不兼容。

例如,假设MyWidget继承自QWidget,同时也声明了Q_OBJECT宏,

     QObject *obj = new MyWidget;

QObject类型的变量obj实际上指向一个MyWidget对象,因此我们可以这样进行类型转换:

     QWidget *widget = qobject_cast<QWidget *>(obj);

到MyWidget的转型可以成功是因为qobject_cast()并没有对Qt内建对象和定制的扩展对象分别对待。

     QLabel *label = qobject_cast<QLabel *>(obj);
     // label is 0

另一方面到QLabel的转型则会失败,指针会被设置为0。这样使得我们可以在运行时根据对象类型,对不同类型的对象进行不同的处理:

   if (QLabel *label = qobject_cast<QLabel *>(obj)) {
       label->setText(tr("Ping"));
   } else if (QPushButton *button = qobject_cast<QPushButton *>(obj)) {
       button->setText(tr("Pong!"));
   }

尽管我们可以在不用Q_OBJECT宏和原对象信息的情况下仍旧使用QObject作为基类,但是像信号和槽以及其他这里描述的特性将无法使用。从元对象系统的观点来看,一个没有元对象代码的QObject子类和其最接近的有元对象代码的祖先是等同的。这也就意味着,QMetaObject::className()将不会返回你的类的真实的名字,而是该类某一个祖先的名字。

因此,我们强烈建议所有QObject的子类都是用Q_OBJECT宏,不管你实际上是否使用信号和槽,以及属性。

参见 QMetaObjectQt's Property System,  Signals and Slots.

原文链接:http://doc.trolltech.com/4.6/metaobjects.html

欢迎转载,请注明出处: http://blog.csdn.net/aladdina

Qt 元对象系统(Meta-Object System)的更多相关文章

  1. Qt 元对象系统(Meta-Object System)(不管是否使用信号槽,都推荐使用)

    Qt 元对象系统(Meta-Object System) Qt的元对象系统基于如下三件事情: 类:QObject,为所有需要利用原对象系统的对象提供了一个基类. 宏:Q_OBJECT,通常可以声明在类 ...

  2. 深入了解Qt(二)之元对象系统(Meta-Object System)

    深入了解Qt主要内容来源于Inside Qt系列,本文做了部分删改,以便于理解.在此向原作者表示感谢! 在Qt Meta Object System-元对象系统这篇文章中,从底层实现的源码剖析了元对象 ...

  3. 解析Qt元对象系统(五) Q_INVOKABLE与invokeMethod(automatic connection从Qt4.8开始的解释已经与之前不同,发送对象驻足于哪一个线程并不重要,起到决定作用的是接收者对象所驻足的线程以及发射信号(该信号与接受者连接)的线程是不是在同一个线程)good

    概述查看Qt源码可知,Q_INVOKABLE是个空宏,目的在于让moc识别. 使用Q_INVOKABLE来修饰成员函数,目的在于被修饰的成员函数能够被元对象系统所唤起. Q_INVOKABLE与QMe ...

  4. Qt元对象系统简介

    在Qt中提供了c++的扩展,提供了一种元对象系统的机制,(meta-object-system)的机制.其中包含了信号与槽的内部机制,能够访问到QObject子类的元对象信息的功能. Q_OBJECT ...

  5. 解析Qt元对象系统(四) 属性系统(确实比较方便)

    官方解释 我们在Qt源码中可以看到一个QObject的子类经常会用到一些Q_开头的宏,例如QMainWindow类开始部分代码是这样的: Q_PROPERTY(QSize iconSize READ ...

  6. qt 元对象系统

    元对象系统 Qt中的元对象系统是用来处理对象间通讯的信号/槽机制.运行时的类型信息和 动态属性系统. 它基于下列三类: QObject类: 类声明中的私有段中的Q_OBJECT宏: 元对象编译器(mo ...

  7. 6、Qt Meta Object system 学习

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

  8. Qt Meta Object system 学习

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

  9. Qt对象模型之二:对象树与元对象系统

    一.对象树的概念 Qt中使用对象树(object tree)来组织和管理所有的QObject类及其子类的对象.当创建一个QObject时,如果使用了其他的对象作为其父对象(parent),那么这个 Q ...

随机推荐

  1. logstash安装

    1.下载并安装公共签名密钥 rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch 2.创建镜像源文件:/etc/yum.rep ...

  2. node的3大作用域

    除了持久性存储外,想要内存也可以存入数据,来做计算什么数据都存入访问一便数据库,效率就太低了 java有3大作用域request 指在一次请求的全过程中有效,即从http请求到服务器处理结束,返回响应 ...

  3. Jquery Easy UI Datagrid 上下移动批量保存数据

    DataGrid with 上下移动批量保存数据 通过前端变量保存修改数据集合,一次性提交后台执行 本想结合easyui 自带的$('#dg').datagrid('getChanges'); 方法来 ...

  4. Pivot 和 Global 的一些总结

      相信大家一定有在 Unity 編輯器上看到這樣功能 這邊會跟大家說明這項功能有什麼用處     Pivot  意思為,輔助編輯的工具標示,會顯示在第一個選取的物件身上. Center 意思為,輔助 ...

  5. eclipse 编译的时候 自动把SDK需要放入libs里面的so文件给删除了

    解决方法: 右击Project,选Properties->Builders, 把CDT Builder 关掉. 这样就不会编译了.包括c++的代码也不会编译.. 治标不治本啊...以后c++代码 ...

  6. spark关于join后有重复列的问题(org.apache.spark.sql.AnalysisException: Reference '*' is ambiguous)

    问题 datafrme提供了强大的JOIN操作,但是在操作的时候,经常发现会碰到重复列的问题.在你不注意的时候,去用相关列做其他操作的时候,就会出现问题! 假如这两个字段同时存在,那么就会报错,如下: ...

  7. hTML5 多图上传预览

    <p> <label>请选择一个文件:</label> <input type="file" id="file" mu ...

  8. python3.6 pyinstaller 打包exe

    现在的pyinstaller 最新版本已经支持python3.6版本的打包了只需要进行如下的操作即可 1. pip install pyinstaller 2. pip install --upgra ...

  9. iis日志时间与本地日期不一样

    iis日志里面的时间是 UTC时间,所以要自已加时区进行转换:即 utc时间+8小时:

  10. 编写和运行简单的"Hello World"操作系统内核

    通常编写一个操作系统内核是一项浩大的工程.但我今天的目标是制作一个简单的内核,用比较方便的方法在虚拟机上验证它能够被grub装载和运行,并且可通过gdb进行调试,为接下去的工作创造一个基础环境. 首先 ...