(转自: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. hdu6215 Brute Force Sorting

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6215 题目: Brute Force Sorting Time Limit: 1000/100 ...

  2. 【转】阿里巴巴技术专家杨晓明:基于Hadoop技术进行地理空间分析

    转自:http://www.csdn.net/article/2015-01-23/2823687-geographic-space-base-Hadoop [编者按]交通领域正产生着海量的车辆位置点 ...

  3. 【Q2D】如何导出自定义C++类给框架使用

    本文基于Quick cocos2d x这个游戏框架,为了行文流畅,后面都简称Q2D 导出自定义c++类给项目使用已经有了现成的例子了 详见:http://quick.cocos.org/?p=235 ...

  4. Ubuntu server 安装的mysql数据库忘记密码的解决方法

    客户端连接时报错MySQL数据库出现:Error 1045错误时,就表明输入的用户名或密码错误被拒绝访问了. 解决办法可以分为以下几步: 1.修改mysql配置文件,使得可以无密码登录mysql su ...

  5. c调用c++编的dll,c++调用c编写的dll,extern “C”的用法

    转自:http://blog.csdn.net/life_is_too_hard/article/details/52137271 c和c++不能直接相互调用,主要是因为c++有重载函数的功能,为了区 ...

  6. Zabbix 触发器函数方法整理

    函数介绍 abschange 参数:忽略 支持类型:float,int,str,text,log 作用:返回最近获得的值与之前获得值差的绝对值,对于字符串类型:0表示相等,1表示不同 avg 参数:秒 ...

  7. C++类中成员变量的初始化总结(转帖)

    本文转自:C++类中成员变量的初始化总结 1. 普通的变量:      一般不考虑啥效率的情况下 可以在构造函数中进行赋值.考虑一下效率的可以再构造函数的初始化列表中进行.  1 class CA  ...

  8. 20145324 《Java程序设计》第10周学习总结

    20145324 <Java程序设计>第10周学习总结 教材学习内容总结 1.网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输 2.在实际传输数据以前需要将域名转换为IP地 ...

  9. 20145328 《Java程序设计》第10周学习总结

    20145328 <Java程序设计>第10周学习总结 资料学习内容总结 网络编程 13.1 网络概述 网络编程技术是当前一种主流的编程技术,随着联网趋势的逐步增强以及网络应用程序的大量出 ...

  10. js 自定义事件观察者模式(发布/订阅)

    /* * 示例: * Event.create("namespace1").listen('click', function(a){ * console.log(a); * }); ...