前言
学以致用,通过QT框架的学习,一边实践,一边探索编程的方方面面.
参考书:<Qt 6 C++开发指南>(以下称"本书"),继承关系沿用本书说法:父类/子类,而非传统C++使用基类/派生类
标识说明:概念用粗体+倾斜.重点内容用(加粗黑体)---重点内容(红字)---重点内容(加粗红字),
本书原话内容用深蓝色标识,比较重要的内容用加粗倾斜下划线深蓝色标识
引入
Qt第2部分的代码化UI设计等内容没有源码参考,和可视化UI设计差不多("挺傻")所以不做解读
Qt框架功能是本书的核心内容.虽没有源码参考,也可想一些办法去还原.
概述
Qt框架包括很多模块.Qt对标准C++进行了扩展,引入了元对象系统.元对象系统的核心特性及其应用,包括属性系统,信号与槽,对象树等.本章还介绍Qt编程中常用的一些类的使用方法,包括容器类,QVariant,QFlags等.
模块
Qt是一个跨平台开发框架,他包含许多功能模块.一个模块针对一个编程主题,本书后续基本上是每章介绍一个功能模块的编程使用方法.
---解读:模块是基于标准的多种功能的实现.硬件被抽象成标准,标准被集成为模块,模块组成框架.
模块的特点:
1.封装了硬件标准和系统内核函数,实现定义的功能.
2.封装形式可以是函数可以是类,再形成文件,组成框架,并可以被编程语言使用.
模块不光是在Qt中有,在其他框架里也有.他实现的功能由写框架的程序员编写.使用框架的程序员可以继续开发.笔者认为框架功能都是比较基础的,占用内存少,有扩展空间
举个例子:程序员想写个和鼠标有关的模块,命名为QMouse,假定封装形式为类.鼠标通常作为事件出现在框架里,所以鼠标类里只采集信号.
/*伪代码*/
class QMouse{
public:
enum class MouseState{state1,state2,...};
MouseState getMouseState(Sensor sr){
if(sr==?)
return state1;
else if(sr==??)
return state2;
};
}
这里定义了一个叫Sensor的类,他的底层是鼠标光电传感器传来的数据,比如左键右键点击(单击,双击),鼠标(上下左右)移动的距离,中键滚轮滑动等---假设已被封装到鼠标使用的标准中.
模块的定义考虑的内容还很多, 硬件部分是一些寄存器,写好硬件驱动,使硬件和系统内核关联.然后系统内核向上提供标准供程序员使用.
基础模块和附加模块
本书P45第一段:Qt Core模块是Qt框架的核心,其他模块都依赖此模块.注意在P44Qt Core模块功能描述:这个模块是Qt框架的核心,定义了元对象系统对标准C++进行扩展.元对象系统将在后面分析.
本书P45第二段:Qt附加模块是一些能够实现特定功能的模块.
模块有些什么内容可以经常拿出来读一读,因为其他地方也可以用到,可以当作"需求"来看.
Qt全局定义
本书P45最后一段:头文件<QtGlobal>包含Qt框架中的一些全局定义,包括基本数据类型、函数和宏.一般的Qt类的头文件都会包含这个头文件,所以用户程序中无须包含这个头文件就可以使用其中定义.
---解读:不需要包含<QtGlobal>这个头文件,因为已被其他Qt头文件所包含---重复包含
数据类型定义
本书P46举了个例子
typedef signed char qint8;
这是标准C/C++中的类型别名定义,也很容易读懂,表示有符号8位数;比如quint8表示无符号8位数.其他类型大致相同.有1个比较特别:qfloat16表示16位浮点数---在C/C++中浮点数是32或64位.注意使用这个数据类型需要包含头文件<QFloat16>.
函数
一些数值处理的函数,以函数模板形式出现---输入输出参数类型使用了模板类型
另一些基础数学运算函数在<QMath>头文件中定义,如三角运算函数等.
宏定义
在C语言中宏一般是给自定义数据取个名字,或者表示简单的函数.在Qt中宏有更多的用处,比如元对象系统的导入用了Q_OBJECT.他不是标准C/C++的写法,中间用到了解释器/编译器,所以可以暂时略过.
Qt元对象系统概述
元对象系统是Qt核心模块Qt_core的核心内容,是核心中的核心.重要程度不言而喻.对使用者而言,也不是很难,只要掌握一些类方面的知识完全能看懂.
Qt元对象系统建立的基础
1>QObject类是所有使用元对象系统的类的基类
2>必须在一个类开头部分插入宏Q_OBJECT,这样才可以使用元对象系统
3>MOC为每个QObject的子类提供必要的代码来实现元对象系统的特性.
QObject类
表3-5列举出了元对象系统特性相关的函数,注意:只列出了返回值类型,若干形参(或0个)未列出
表中的元对象部分将在QMetaObject类中说明,类型信息,动态翻译,信号与槽,属性系统在后面,看对象树.
本书P48最后一段:对象树指的是表示对象之间从属关系的树状结构.例如在一个窗口中,组件都有父容器,窗口是顶层容器.在图2-10中,右侧对象检查器里的目录树就体现了窗口上组件的层次关系,可以看作对象树.
=============================内容分割线↓===================================
笔者尝试给出对象树类型设计(仅供参考,不保证准确)
方案一:
class QWidget:public QObject{}; //QWidget(窗口类)继承QObject
class QRadioButton:public QObject{}; //QRadioButton(单选框)继承QObject
class QPushButton:public QObject{}; //QPushButton(按钮)继承QObject
/*其他所有窗口组件类都继承QObject*/
class QWidget{
vector<QObject*> qtp;
}
简单说明:遍历qtp对象,每一个对象元素(QObject*类型对象)代表了一个动态数组---表示若干个QRadioButton或QPushButton对象.这种写法和笔者以前提到的矩阵图形类相似,又有些区别,这个表达范围更广,原因在于QObject*可以指向他的一切子类对象.QRadioButton或QPushButton对象可以继续向下扩展(继续在对象属性中添加vector<QObject*>对象或QObject*对象),以此建立起一个树形结构(理论无限).
树形结构类型的建立有两点:一是继承关系,二是包含父类指针(集合).当包含指针时,表示单个子类对象集合(一维数组),当使用集合时,表示多个种类的子类对象集合(二维数组)
注意:这里需要对C++语法有一定理解,也可能含某种设计模式,如果没这方面知识储备可跳过
方案二:
依然保持继承关系,每个对象下面固定某些数据类型的集合,这种办法比较直观,效果不如第一种
有了对象树定义,可以实现表3-5中和对象树相关的函数.
注意:在QWidget析构函数中要把传入的指针指向的对象删除(上图代码未给出),否则有两个后果:一是会造成内存泄漏,二是做不到本书P49第一段中"对象树中的某个对象被删除时,他的子对象会被自动删除,所以,一个窗口被删除时,他上面的所有界面组件也会被自动删除".同时适用于其他树形类对象.
=============================内容分割线↑===================================
还有一点,本书表3-5中对象树功能写的是"返回子对象列表","返回父对象指针",含义是"当前类包含对象的列表"以及"当前对象被包含在哪个类的对象的指针".这里指的是"包含"而不是"继承"关系
小结
Qt框架功能概述第一部分简析.