Qt的元对象(Meta-Object)系统简介(转)
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,说明对象类型不兼容。
当某一个Object emit一个signal的时候,它就是一个sender,系统会记录下当前是谁emit出这个signal的,所以你在对应的slot里就可以通过sender()得到当前是谁invoke了你的slot,对应的是QObject->d->sender。
有可能多个Object的signal会连接到同一个signal(例如多个Button可能会connect到一个slot函数onClick()),因此这是就需要判断到底是哪个Object emit了这个signal,根据sender的不同来进行不同的处理。这时就要用到qobject_cast()。
例如,假设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宏,不管你实际上是否使用信号和槽,以及属性。
例子:
connect(pushButton_2,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));
connect(pushButton,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));
void MainWindow::on_pushButton_clicked()
{
QPushButton*pt=qobject_cast <QPushButton*>(sender());
if(!pt)
return;
QString str;
if (pt = = pushButton)
str="1";
else if (pt = = pushButton_2)
str="2";
}
转载于:https://www.cnblogs.com/qq78292959/archive/2012/08/20/2648099.html
Qt的元对象(Meta-Object)系统简介(转)相关推荐
- Qt 如何实现的 Meta Object
Qt 如何实现的 Meta Object 2009-11-01 11:57 741人阅读 评论(0) 收藏 举报 qtsignalcallbackobjectclasstable (文章转贴自guil ...
- Qt 原理-MOC(1)Meta Object Compiler
Qt程序编译两个步骤: 1. qmake 生成Makefile文件,Makefile.Debug, Makefile.Release 主要是通过MOC(Meta Object Compiler) 元对 ...
- 基于Qt5.14.2和mingw的Qt源码学习(三) — 元对象系统简介及moc工具是如何保存类属性和方法的
基于Qt5.14.2和mingw的Qt源码学习(三) - 元对象系统简介及moc工具是如何保存类属性和方法的 一.什么是元对象系统 1.元对象系统目的 2.实现元对象系统的关键 3.元对象系统的其他一 ...
- qt中实现息屏开平mousepress_Qt元对象(Meta-Object)系统与反射
前言 给部门内部培训Qt相关的一些注意点用的,我提取出来放到自己的博客上了.欢迎各位大佬吐嘈 原文链接 Qt元对象(Meta-Object)系统与反射 - C++ Programerwww.cryf ...
- Qt元对象系统(Meta-Object)(四)、Moc源代码分析
目录 前言 打开源代码 源码追踪解析 总结 前言 前面讲了那么多,Qt的元对象系统是多么多么厉害,多么多么好,那么Moc是具体是怎么工作的,所谓源码面前,了无秘密,下面让我们一探究竟. 打开源代码 ...
- Qt工作笔记-Qt元对象系统解析【2合1】
博文转载地址: https://blog.csdn.net/spwper/article/details/51332187 说Qt信号与槽是一个很好机制,不如说Qt的元对象系统很强大.这也是大家讲Qt ...
- linux创建自定义组件qt,QT中的元对象系统:创建自定义的QT类型
原创文章,转载请注明出处,谢谢! 作者:清林,博客名:飞空静渡 QVariant可以表示QT中的大部分类型,它和pascal中的variant类型或c中的void类型有点相似,不过它的使用和c中的un ...
- Qt元对象系统:QMetaObject
一.描述 此类包含有关Qt对象的元信息.Qt为应用程序中使用的每个 QObject 子类创建一个 QMetaObject 实例,该实例存储 QObject 子类的所有元信息. 二.静态成员函数 1.Q ...
- QT Embedded二三事之QObject的元对象
一.元对象 元对象被称做是meta object.在运行时刻(runtime),能够提供对象的运行时信息. 在C++语言发展的早期,C++语言本身没有定义对象的运行时信息,如输出类的名称,父类的名称 ...
最新文章
- 深度学习加速器堆栈Deep Learning Accelerator Stack
- ai外呼营销系统_为了让居民预约口罩少出门,长宁这个街道使用AI技术智能语音外呼系统...
- 技术演讲的技巧和经验
- 7-13 镖局运镖 (10 分)
- mysql5.5二进制安装,mysql5.5.28 通用二进制安装
- 博科SAN交换机zone配置(华为SNS系列交换机为例OEM博科)
- AndroidStudio_Android Studio项目中报Call requires API level 18 (current min is 16)---Android原生开发工作笔记232
- linux 超好用的命令行工具
- 编程之美读书笔记1.3 —— 一摞烙饼的排序
- Windows 7 极限精简 x86 x64 2018年度版
- 怎么实现word自动分级标题
- stm32 定时器_基于STM32定时器ETR信号的应用示例
- 配置Java远程监控授权(Java Mission Control)
- Github-Client(ANDROID)开源之旅(四) ------ 简介Roboguice
- python怎么从excel获取数据_python如何读取excel表数据
- 人体动作捕捉-坐标转换
- 如何加密html文件怎么打开,文件加密巧用IE浏览器
- 查询一年1、1-2月、1-3~一直到1-12月
- deepin 15.3 安装“Chrome Flash插件”折腾记
- Spark创建空的DataFrame
热门文章
- 乡镇快递站20万入股50%,每天派件600,是否靠谱?
- 《孩子,你如此优美:一位作家母亲的家教笔记》
- 流水线技术在高速数字电路设计中的应用
- C/C++实现模糊控制,借助MATLAB辅助设计和fis.c文件
- Pygame 使用Djkstra广度搜索寻找迷宫(相对)最短路径
- oracle 日期6,EF 6与Oracle - 如何加入日期字段?
- dijkstra算法_Python实现图的经典DFS、BFS、Dijkstra、Floyd、Prim、Kruskal算法
- android中怎么保存checkbox中的checked属性_Vue 精粹:v-model指令在组件中怎么玩
- FOI冬令营 Day 3
- LVS--NAT模型配置