前言
学以致用,通过QT框架的学习,一边实践,一边探索编程的方方面面.
参考书:<Qt 6 C++开发指南>(以下称"本书"),继承关系沿用本书说法:父类/子类,而非传统C++使用基类/派生类
标识说明:概念用粗体+倾斜.重点内容用(加粗黑体)---重点内容(红字)---重点内容(加粗红字),
本书原话内容用深蓝色标识,比较重要的内容用加粗倾斜下划线深蓝色标识
引入
可视化UI设计,是一种"傻瓜"化的编程.但正因为看起来简单,尽量不要出错.
资源文件的创建
1>准备工作:先建立一个项目,在项目根目录下创建一个资源文件夹,放入资源文件(这里是图标)
2>右键点击项目管理目录树中的项目名称,选择"添加新文件",注意本书P24第6段:"打开New File or Project 对话框,选择Qt分组里的Qt Resource File",没找到怎么做的(可能是笔误)
如图
3>在弹出的对话框中,选择"Qt Resource File",点击"选择..."如图
4>在弹出对话框中,输入资源文件名(沿用本书写法,输入"res",系统自动添加后缀qrc),路径选择项目安装目录---默认即可(笔者这里路径选了资源文件夹的路径到了images,会稍微有点区别但不会影响结果).如图
下一步点"完成"
5>在项目管理目录树中,点击"添加前缀",给资源文件添加前缀,如下图中添加了"/icons"的前缀:
6>点击"添加文件",把资源文件夹中的图标文件全添加进来---选中后点击"打开"如图
本书对资源文件讲解不多.资源文件是十分重要的,他表示可以使用其他类型的数据文件,比如这里使用图标文件.bmp,引申一下,如果Qt支持.wav,.ape,.flac格式的音乐文件,也支持视频文件.mpeg等等,将会极大丰富Qt项目的内容.
窗口界面设计
本书P24最后一段: 双击文件dialog.ui就可以打开Qt Designer对窗口界面进行可视化设计.
界面设计的流程很简单:把左边过滤器里的元素拖动到设计窗口并修改属性.具体操作自己摸索.本书P25第二段举了一个例子---使用资源文件作为属性:要为一个QPushButton按钮设置图标,只需在属性编辑器里修改其icon属性.在icon属性值输入框的右端下拉列表框里选择Choose Resource(笔者使用的是Choose File),就可以从项目的资源文件中选择图标.
可视化UI很容易操作,这对做美工的人来说是好事,可以花更多时间来研究界面的美观,而对没什么画面美感的程序员不是那么友好.当然工作侧重点不一样,程序员可以在程序结构上下功夫,让程序占更小的内存,有更高的运行效率等等.
窗口对象命名问题
本书P25第一段:在UI可视化设计时,对于需要在程序中访问的界面组件访问的界面组件,例如各个按钮、需要读入输入的编辑框、需要显示结果的标签等,应该修改其对象名称.如图
本书P25讲了几点界面组件需要注意的事项,笔者综合起来做几点小结:
1>对象名称建议修改
图中元素(除了窗体名称)基本上都没有使用默认名称.以QPushButton类为例,他产生的对象默认名为PushButton1,PushButton2,读起来很生涩.改了以后几乎一眼看出是什么意思---如btnOK---一个叫OK的按钮,btnExit---一个叫Exit的按钮.后面根据需要可以给按钮添加槽函数.
但是注意不要在编程过程中改来改去,建议只修改一次(比如开始时候修改以后就不要动了).
2>窗体名称不建议修改.
注意上图,鼠标选中的是QDialog对象Dialog,在图片右下方的属性中,QObjiect类中属性为objectName,值为Dialog.笔者做了试验,把值改为D1(其他什么名字都可以,只要不是Dialog),构建程序---调试(Debug)或者发行(Release)会报错.原因是dialog.ui和ui_dialog.h相关联,改变了dialog的名称,必须和主程序等其他4个文件的名称一起更新,否则编译时找不到对应文件.
3>组件属性有默认值,可以还原.
界面布局管理
所谓布局,就是指界面上组件的排列方式.
布局分了两种:组件布局和窗体布局.界面的设计用了一种模型:元素组成容器,容器组成窗体.
1>容器布局
先建立一个容器类组件,把元素放进去.本书P25最后一段中,将3个复选框(QCheckBox类对象)放在一个分组框(QGroupBox类对象)里.这3个复选框的容器就是这个分组框,同时分组框也是3个复选框的父容器.
=============================内容分割线↓===================================
思考父容器是怎样定义的?如下:
//伪代码
class QGroupBox{ //分组框QGroupBox类定义
private:
vector<QObject> vos;
public:
QGroupBox::~QGroupBox{
把vos的对象清空;
}
};
class QCheckBox:public QObject{} //复选框QCheckBox类定义
注意这里不要对象指针或者对象引用,直接用vector.在析构函数定义中,把容器的对象删除即可.
问题很明显, QGroupBox只是容器类型的一种,那么其他容器怎么办?假设有一个容器基类container
class QGroupBox:public Container{}; //分组框QGroupBox类定义
class QToolBox:public Container{}; //有一个QToolBox也继承Container
还有一些小问题,如果QObject是所有类的基类,那么应该还有
class Container:public QObject{} //Container直接或间接继承自QObject
=============================内容分割线↑===================================
上述父容器的定义,实现了当父容器对象被删除时,其包含元素也全部删除.
2>布局操作
分为4种:垂直方向布局,水平方向布局,网格布局,表单布局.还是挺直观的.
注意:布局操作时先备份,如果一边设置布局一边点保存,可能出现布局无法恢复---全灰色然后已设计好的元素无法继续操作.如果不想备份,在最终布局决定前,不要点保存.
3>窗体布局
和容器布局相似,只是操作的时候要选中整个窗体(容器布局是选中容器后操作)
4>Spacers水平间隔和垂直间隔
这块内容比较简单,稍微看看就可以了.
两个小问题
1>本书samp2_2项目中,如何实现对话框中的几个按钮控制文本显示效果的?本书没有讲,笔者感觉是一个漏洞(也可能作者觉得越讲需要牵涉的内容越多,干脆不讲).笔者看了属性,发现所有界面元素对象的设置在这里相同:
不知道是否有内在的联系,有一种约定:在对话框类型QDialog中,输入文本类型QPlainTextEdit,复选框类型QCheckBox,单选框类型QRadioBox,按钮类型QPushButton,都采取这种设置,即把效果用在文本中
2>注意建立项目时,采用全英文路径,否则编译时无法通过,报错:Qt 文件名、目录名或卷标语法不正确.
小结
可视化UI的简单理解
P27~P32之间的部分内容:信号与槽简介,Qt项目构建基本原理,伙伴关系等内容放到后面再看