Qt之Q_OBJECT宏

在这里插入图片描述
类中漏掉Q_OBJECT宏会导致connect函数不能使用。

如果没有Q_OBJECT,则不会生成多余的cpp文件
在这里插入图片描述加上Q_OBJECT即使不用connect等相关函数都会生成moc_xxx.cpp文件
在这里插入图片描述其中,cpp文件里面定义了结构体和几个函数,.h文件里面定义了很多宏。

只有继承了QObject类的类,才具有信号槽的能力。所以,为了使用信号槽,必须继承QObject。凡是QObject类(不管是直接子类还是间接子类),都应该在第一行代码写上Q_OBJECT。不管是不是使用信号槽,都应该添加这个宏。这个宏的展开将为我们的类提供信号槽机制、国际化机制以及 Qt 提供的不基于 C++ RTTI 的反射能力。因此,如果你觉得你的类不需要使用信号槽,就不添加这个宏,就是错误的。其它很多操作都会依赖于这个宏。
  由于 moc 只处理头文件中的标记了Q_OBJECT的类声明,不会处理 cpp 文件中的类似声明。因此,如果我们的类位于 main.cpp 中,是无法得到 moc 的处理的。解决方法是,我们手动调用 moc 工具处理 main.cpp,并且将 main.cpp 中的#include “xxx.h”改为#include “moc_xxx.h”就可以了。不过,这是相当繁琐的步骤,为了避免这样修改,我们还是将其放在头文件中。许多初学者会遇到莫名其妙的错误,一加上Q_OBJECT就出错,很大一部分是因为没有注意到这个宏应该放在头文件中。

MOC

  QT的元对象编译器MOC(Meta-Object Compiler)是一个预处理器,在源程序被编译前先将这些QT特性的程序转为标准的C++兼容的形式**,然后再被标准的C++编译器进行编译。也就是为什么在使用信号和槽的机制的类里,必须添加一个Q_OBJECT宏的原因,只有添加了这个宏,moc才能对类里的信号与槽代码进行预处理。
  构建项目时MOC工具读取C++源文件,当它发现类的定义里有Q_OBJECT宏时,它会为这个类生成另外一个包含有元对象支持代码的C++源文件,也就是moc_xxx.cpp文件,这个生成的源文件连同类的实现文件一起被编译和连接
  Q_OBJECT是Qt实现元编译系统的一个关键宏,这个宏展开后,里边包含了很多Qt帮助我们写的代码,包括了变量定义、函数声明等等,

Qt 使用 moc,为标准 C++ 增加了一些特性:

信号槽机制,用于解决对象之间的通讯,这个我们已经了解过了,可以认为是 Qt 最明显的特性之一;
可查询,并且可设计的对象属性;
强大的事件机制以及事件过滤器;
基于上下文的字符串翻译机制(国际化),也就是 tr() 函数,我们简单地介绍过;
复杂的定时器实现,用于在事件驱动的 GUI 中嵌入能够精确控制的任务集成;
层次化的可查询的对象树,提供一种自然的方式管理对象关系。
智能指针(QPointer),在对象析构之后自动设为 0,防止野指针;
能够跨越库边界的动态转换机制。

通过继承QObject类,我们可以很方便地获得这些特性。当然,这些特性都是由 moc 帮助我们实现的。moc 其实实现的是一个叫做元对象系统(meta-object system)的机制。正如上面所说,这是一个标准 C++ 的扩展,使得标准 C++ 更适合于进行 GUI 编程。虽然利用模板可以达到类似的效果,但是 Qt 没有选择使用模板。按照 Qt 官方的说法,模板虽然是内置语言特性,但是其语法实在是复杂,并且由于 GUI 是动态的,利用静态的模板机制有时候很难处理。而自己使用 moc 生成代码更为灵活,虽然效率有些降低(一个信号槽的调用大约相当于四个模板函数调用),不过在现代计算机上,这点性能损耗实在是可以忽略。

参考

https://blog.csdn.net/u011555996/article/details/124438676
https://zhuanlan.zhihu.com/p/620384700
https://www.devbean.net/2012/09/qt-study-road-2-objects-model/
https://blog.csdn.net/u012564117/article/details/102631264

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值