1,Qt中的反射自省机制。
- 没有用c++原生的typeid等方法。原生的c++自省反射机制没有完全标准化,各个编译器的实现不一致,导致ABI接口不兼容。
- Qt Core中的元对象系统是(Meta Object System),元对象系统,提供信号与槽的实现,对象间的通信,类信息的运行时识别,是对标准c++的扩展。
2,Qt中的设计
- 类实现私有化设计,引入q指针和p指针,分离了接口和成员数据,维护了接口的稳定。
- 观察者模式,信号与槽,event分发机制。
3,Qt中的元对象系统
- 元系统,指的是自动生成代码的代码系统。
主要由:Q_OBJECT宏,MOC编译器,QObject基类组成。
4, Qt框架的编译过程:
MOC编译器的作用就是自动添加QOBJECT宏的展开代码,注册信号与槽函数,注册类属性信息,添加必要的元对象系统代码。
5,Q_OBJECT宏展开
#define Q_OBJECT \
public: \
Q_OBJECT_CHECK \
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 {}; \
QT_ANNOTATE_CLASS(qt_qobject, "")
- static const QMetaObject staticMetaObject;
- virtual const QMetaObject *metaObject() const
- virtual void qt_metacast(const char)
- virtual int qt_metacall(QMetaObject::call,int,void**)
- static void qt_static_metacall(QObject*,QMetaObject::Call,int,void**)
元对象系统的核心思想是利用moc编译器,识别源码中的Q_OBJECT宏,添加一个静态成员对象staicMetaObject,扫描类中的所有属性和方法,把属性,方法,信号,槽函数都注册到静态对象中,并提供一个对外获取静态对象地址的方法:metaObject(),实现Qt的反射机制。
6,信号与槽
Qt中的信号与槽的连接方式:
// 传统Qt是连接方式
class QObject{};
QObject::connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(qT4_slot()));
//Qt5的新方法,在编译的时候就会有监测,如果我们手误操作失误,就会出现问题
QObject::connect(ui->pushButton_2,&QPushButton::clicked,this,&Widget::qT5_slot);
//Qt5 Lambda表达式
QObject::connect(ui->pushButton_3,&QPushButton::clicked,[=](){qDebug()<<"lambda 表达式";});
通过观察者模式,通过元对象中遍历所有槽函数。
7,QObject类功能
Object类的主要功能:
- 管理parent,children节点,采用多叉树结构。
- 定时器.
- 线程支持.
- 事件和事件过滤的实现.
- 获取MetaObject的方法。
- 提供信号与槽的connect虚方法。
8,事件机制
对于Qt应用来说,所有事件分位两类:1,系统事件.2,应用事件.
- 系统事件包括:
- 鼠标点击事件.
- 键盘事件
- 软中断事件.
- 用户事件:
代码中用send,post出发的事件.
对于Qt应用来说,系统事件是被动感知的,操作系统内核负责监听所有硬件的事件触发.统一广播给上层应用.Qt应用只订阅自己感兴趣的事件,对特定的事件如鼠标左键点击,订阅后,在自己的界面内的槽函数内响应.
Qt的Object类中有两个虚函数 event(QEvent* event)
和event Filter(QObject* watched,QEvent* event)
分别用于事件分发和事件过滤.
9, QML
- Qml是一种脚本语言,基于js引擎,是JavaScript语言的扩展语言,相较于传统的Qt开发方式,更易于上手,在移动设备上性能更好.
- 这几年javascr引擎的快速发展,jit技术得到空前发展,脚本语言的执行效率得到大幅提高,相比之前脚本语言执行在虚拟机中,现在的脚本语言的在运行时及时编译为机器指令.效率得到发福提升.
- Qt Quik是QML的扩展库,封装可大量实用控件.
- QML和传统的Widget开发方式,是完全不同的两个分支.
10,Qt缺点
- 优点:
- 开发快,简易上手,模块使用方便。
- 跨平台。
- 完善,资料丰富。
- 缺点:
- 编译慢。牺牲了运行效率。
- 包体冗余。
- 相比标准c++,牺牲了内存占用。
- 引入源系统编译器,增加了代码的不透明度,不利于性能优化。
适合简单的工具开发,对内存和包体要求宽松的环境。不适合大型工程软件,对内存和包体有严格限制的环境。