一、基础组件
1. Designer程序(掌握)
Designer程序是一款用于设计Qt界面的应用程序,本身可以作为独立程序使用。
![](https://img-blog.csdnimg.cn/img_convert/c262cf102d366f5dc6ebdaf223e1db7c.png)
Designer保存的文件格式为.ui,当Qt项目创建的过程中选择“创建界面”时,Qt项目中就会有一个ui文件,双击ui界面文件,就可以使用Qt Creator内置的Designer程序,如下所示。
![](https://img-blog.csdnimg.cn/img_convert/745d4d2a3da11d72b88dfb903322a734.png)
![](https://img-blog.csdnimg.cn/img_convert/5bb93974097859eaa77d1b489e8e95f4.png)
Designer程序的区域划分如下所示。
![](https://img-blog.csdnimg.cn/img_convert/38cf80ad54bbc0fee4f44dcbcd74ffbb.png)
2. 布局 Layout(掌握)
可以认为布局是一个透明的盒子,不同的组件放置到布局中,遵循布局的规则,组件按照规则自动摆放。
布局有4种:
![](https://img-blog.csdnimg.cn/img_convert/3435d7e6b79b2d89b47539c9241af6a8.png)
垂直布局指的是布局内部的组件按照垂直方向排成一排;水平布局指的是布局内部的组件按照水平方向排成一排;格栅布局指的是布局内部的组件按照表格的形式排列;表单布局通常用于录入用户输入的界面。
主要讲解垂直布局与水平布局。
常用属性如下。
![](https://img-blog.csdnimg.cn/img_convert/93b92efc0b2284e05e16735fc5e09861.png)
需要注意的是,布局支持打破、贴合和嵌套。
3. 伸展器(掌握)
用于填充布局的空白。
![](https://img-blog.csdnimg.cn/img_convert/4bde9078e0d8a5246e237871a5ba127f.png)
![](https://img-blog.csdnimg.cn/img_convert/056255e20119fd7e2bc260ce1107f2a2.png)
4. Designer信号槽(了解)
Designer程序也可以配置信号槽的连接。
在Designer中点击F4可以进入信号槽编辑状态,在此状态中信号槽的连接可以直接拖拽,但是只能实现 自带信号→自带槽 的效果。
![](https://img-blog.csdnimg.cn/img_convert/5f01325e3068838f36c29a67e2c032ca.png)
![](https://img-blog.csdnimg.cn/img_convert/4fb50c12c2bfac71b70ec56a7ed1fa83.png)
点击F3可以退出Designer的信号槽模式,上面的步骤也可以使用信号槽编辑器完成。
在Designer中选中发射者,鼠标右键,点击“转到槽”,可以在C++代码中自动创建自定义槽函数,并自动连接。
本节的信号槽连接方法不建议使用,因为会降低代码的维护效率和可读性。
5. 代码布局(了解)
先创建一个不包含ui文件的Qt项目。
dialog.h
#ifndef DIALOG_H#define DIALOG_H#include <QDialog>// 垂直布局#include <QVBoxLayout>#include <QPushButton>class Dialog : public QDialog{ Q_OBJECTpublic: Dialog(QWidget *parent = 0); ~Dialog();private: QPushButton *btn1; QPushButton *btn2; QVBoxLayout *layout;};#endif // DIALOG_H
dialog.cpp
#include "dialog.h"Dialog::Dialog(QWidget *parent) : QDialog(parent){ resize(500,500); // 创建布局对象 layout =new QVBoxLayout(this); btn1 = new QPushButton("A",this); btn2 = new QPushButton("B",this); // 添加两个按钮对象到布局中 layout->addWidget(btn1); layout->addWidget(btn2);}Dialog::~Dialog(){ delete layout; delete btn1; delete btn2;}
6. ui指针(掌握)
ui文件内部实际上是xml语法的代码文件,Designer工具实际上是xml与C++的桥梁。
![](https://img-blog.csdnimg.cn/img_convert/0bd427b56939e16262e11c730227a56a.png)
ui指针可以管理所有在ui文件中设计的组件对象,开发者无需在C++代码中手动创建或销毁这些对象。
![](https://img-blog.csdnimg.cn/img_convert/3428f28d631dc6e5469ddc73afe1d0ea.png)
![](https://img-blog.csdnimg.cn/img_convert/8d0bd3ebe2af8139e3874af695495591.png)
后期的开发都使用这种方式,即不再手动创建和销毁组件对象,非组件对象不被ui文件支持,还是需要手动创建或销毁。
7. 基本组件(掌握)
7.1 QWidget
进入Designer,选择任意一个组件或窗口,都有一些淡黄色的属性,这些属性都来自于共同基类QWidget。
![](https://img-blog.csdnimg.cn/img_convert/2730f12e91b063218e6bb57031d9b62c.png)
7.2 标签 QLabel
用于文字或图片显示。
常用属性如下所示。
![](https://img-blog.csdnimg.cn/img_convert/7c1c86a8195031697cfa983fb2da22a4.png)
QLabel显示图片,要先把图片资源导入到项目中,Qt支持常见图片类型,例如:jpg、png、bmp等。
导入图片到项目的步骤如下所示:
1. 下载相关图片资源,建议使用:
https://cn.bing.com/images/trending?form=Z9LH Bing搜索
https://www.iconfont.cn/plus 阿里巴巴矢量图标库
2. 图片命名为小写英文+数字+下划线的形式,且数字不能开头(个人习惯)。
3. 把图片粘贴到工作目录中。
4. 在Qt Creator中,选中项目名称,鼠标右键,点击“添加新文件”。
5. 在弹出的窗口中,按照下图所示进行操作。
![](https://img-blog.csdnimg.cn/img_convert/04026904f73b8bfc343f8a9ec39aa1ba.png)
6. 为资源文件命名,如下所示。
![](https://img-blog.csdnimg.cn/img_convert/bce2981f8518672c0dbe79e47ca552f7.png)
7. 在项目管理界面,直接点击“完成”,可以看到项目中多了一个.qrc资源文件。
![](https://img-blog.csdnimg.cn/img_convert/114b09c3422228995864d9a9a5f54514.png)
8. 选中qrc文件,点击“添加”---“添加前缀”
![](https://img-blog.csdnimg.cn/img_convert/716fa50977e29204574582e5d34eebe9.png)
9. 再次选中qrc文件,点击“添加”---“添加文件”,选择要导入项目的图片文件即可,后续导入其它图片都直接执行此步骤。
![](https://img-blog.csdnimg.cn/img_convert/aa13800fbffdbcfbe669a9e05e37d8ac.png)
![](https://img-blog.csdnimg.cn/img_convert/f647b173b299f02f4fce7e6cb7e5d1ad.png)
10. 在qrc文件中选中要使用的图片,鼠标右键,点击“复制资源路径到剪切板”。这个资源路径就是在程序中调用图片的路径。
![](https://img-blog.csdnimg.cn/img_convert/35f6e8126a7860696269c0cd2fc5953c.png)
11. 如果要在Designer中使用新导入的图片,需要把项目重新构建
![](https://img-blog.csdnimg.cn/img_convert/214c74697b5602ab6758ad121fdc9ff7.png)
一遍。
示例代码下载链接:https://pan.baidu.com/s/1fGznnydZKpVIesUGxVZhRA
提取码:hqyj
--来自百度网盘超级会员V6的分享
尽量在编程之前先使用Photoshop等工具对图像预先处理,避免在Qt中处理图像,因为程序处理图像非常消耗性能。
7.3 按钮类组件 QAbstractButton
按钮类有一个共同的抽象基类QAbstractButton,因此绝大多数成员都在抽象基类中编写。
![](https://img-blog.csdnimg.cn/img_convert/ef2aeae4033db3632ccd1ea12db87f67.png)
常用属性如下所示。
![](https://img-blog.csdnimg.cn/img_convert/087731c3b3b34251de172565ed2d8c5d.png)
常用信号如下。
![](https://img-blog.csdnimg.cn/img_convert/1559e9b8df12a73712e5b295115506ed.png)
示例代码下载链接:https://pan.baidu.com/s/1OKekO6uBxRwFAUceN8tVrw
提取码:hqyj
--来自百度网盘超级会员V6的分享
有时候界面上的按钮比较多,为每个按钮设置信号槽检测需要编写很多信号槽连接的代码,此时可以使用QButtonGroup对按钮进行批量地信号槽连接。
示例代码下载链接:https://pan.baidu.com/s/1Od5Jl95JStPBRq4I9phQEg
提取码:hqyj
--来自百度网盘超级会员V6的分享
7.4 单行文本输入框 QLineEdit
用于录入用户的文本输入。
常用属性如下所示。
![](https://img-blog.csdnimg.cn/img_convert/c1106df29404022fb104d11599b3c030.png)
常用信号函数如下所示。
![](https://img-blog.csdnimg.cn/img_convert/36ea200e6a934d5c4cb894bb8c5dc8c9.png)
示例代码下载链接:https://pan.baidu.com/s/1wxv33NxlfYTU4-wnQnschQ
提取码:hqyj
--来自百度网盘超级会员V6的分享
7.5 组合框 QComboBox
组合框在某些情况下可以代替QRadioButton,因为组合框比单选按钮的占用空间更小。
组合框中的每个选项被称为Item,Qt Creator翻译为“项目”,后文称呼Item为“选项”。
常用属性如下。
![](https://img-blog.csdnimg.cn/img_convert/48ebc5f46e6f6176ec6e9bdea7ad7b33.png)
常用信号如下。
![](https://img-blog.csdnimg.cn/img_convert/c9c532e22373b5f95634ac3ee178442f.png)
示例代码下载链接:https://pan.baidu.com/s/1E-MtaK-WaU1qhl8mDOL6wA
提取码:hqyj
--来自百度网盘超级会员V6的分享
7.6 一些与数字相关的组件
![](https://img-blog.csdnimg.cn/img_convert/bf6eff339034b8ca78c8418753411dbf.png)
常用属性如下。
![](https://img-blog.csdnimg.cn/img_convert/9e243d65066195c0399536a899647f0d.png)
当value值发生变化时,这几个组件都有对应的信号函数:
void valueChanged(int value) [signal]
示例代码下载链接:https://pan.baidu.com/s/1nO9BfNU79hndhoGq_o-Uog
提取码:hqyj
--来自百度网盘超级会员V6的分享
二、常用类
1. QString 字符串类(熟悉)
QString是Qt的字符串类,使用的是Unicode编码,而不是ASCII编码。Unicode编码支持所有语言的字符,因此每一个字符是一个16位的QChar,而不是8位的char,QString可以完美支持中文。
QString几乎不需要引入头文件,因为所有的组件类都引入了QString的头文件。
Qt是基于C++二次开发的框架,为了兼容一些C++的用法,QString中很多接口是兼容std:string的用法的。
QString的函数太多,不需要完全记住每个函数的函数名称、参数与返回值,只需要认识每个函数的名称,随用随查。
![](https://img-blog.csdnimg.cn/img_convert/4ff4df6a91feb258ba62e1ea06791b6a.png)
示例代码下载链接:https://pan.baidu.com/s/1mact-xHJp3mqIqCDPlCyeQ
提取码:hqyj
--来自百度网盘超级会员V6的分享
2. 容器(掌握)
Qt重新设计的C++中的容器,相比于C++中的容器类,Qt的容器类更加易于使用,例如可以减少可执行文件的体积等。另外,Qt的容器类是线程安全的。
本次选用QList和QMap作为顺序容器和关联容器的讲解类型。
2.1 QList
C++中的list不支持下标,Qt中的QList几乎支持所有的顺序容器操作。本次讲解使用QList保存自定义C++类的对象,因此需要在Qt项目中创建一个C++类。
在Qt项目中创建一个C++类的操作步骤如下:
1. 在Qt Creator中选中,项目名称,鼠标右键,点击“添加新文件”。
2. 在弹出的窗口中,按照下图所示进行操作。
![](https://img-blog.csdnimg.cn/img_convert/2a49c164d978893b3687d469569a2380.png)
3. 在弹出得窗口中编写类名(大驼峰),单击“下一步”。
![](https://img-blog.csdnimg.cn/img_convert/48d4f65e987f19da9299f42270dabe75.png)
4. 在项目管理界面,直接点击“完成”。就可以在项目中看到新创建的类的头文件和源文件。
![](https://img-blog.csdnimg.cn/img_convert/7fc0461d7dd9f0d13d4902acf914043f.png)
查文档时经常会遇见QStringList类型,相当于QList<QString>
使用QList存储自定义C++类对象的示例代码下载链接:
https://pan.baidu.com/s/1ZCJ4QuqOtbIkirD0MHJxcw
提取码:hqyj
--来自百度网盘超级会员V6的分享
2.2 QMap
示例代码下载链接:https://pan.baidu.com/s/1B4ypJqs7OH_AB-g4QZwRYg
提取码:hqyj
--来自百度网盘超级会员V6的分享
3. Qt数据类型(熟悉)
Qt是一种一种跨平台的开发框架,为了确保在各个平台上数据类型具有统一的长度,Qt为常见的数据类型提供了跨平台使用时的替换类型。
![](https://img-blog.csdnimg.cn/img_convert/0236e84b010980d6b9de00b871c4fbd8.png)
另外,Qt中还有一种统一数据类型QVariant,Qt中常见的数据类型都可以与此类型互相转换。
4. 日期时间类 QDateTime(熟悉)
QDateTime用于处理Qt中的日期和时间,此外,QDate类专用于处理日期,QTime专用于处理时间,主要讲解QDateTime类。
常用函数如下所示。
// 获取当前时间到1970年1月1日00:00:00的毫秒差(格林威治时间)qint64 QDateTime::currentMSecsSinceEpoch() [static]
// 返回基于当前时区的日期和时间数据的QDateTime对象,数据基于当前设备QDateTime QDateTime::currentDateTime() [static]
// 格式化QDateTime对象中的数据// 参数为提取的格式// 参数为提取的数据QString QDateTime::toString(const QString & format) const
格式尽量查询官方文档,如果不想看英文,可以使用下面的表格。
![](https://img-blog.csdnimg.cn/img_convert/3beb1810b7c37bee6a6a2781b7528dab.png)
与时间和日期相关的组件有
![](https://img-blog.csdnimg.cn/img_convert/fd33631b781f8dd4cf6dbff351f6593e.png)
三、多窗口编程
1. QMessageBox 消息对话框(掌握)
QMessageBox继承自QDialog,是一个模态对话框(必须优先处理),用于通知用户或录入用户一个问题的答案,Qt预设了四种QMessageBox:
![](https://img-blog.csdnimg.cn/img_convert/43154397e36e159202d73e168996a709.png)
QDialog的派生类几乎都使用静态成员函数直接调用,不需要创建对象。
四种窗口的调用方式一致,如下所示。
![](https://img-blog.csdnimg.cn/img_convert/b86758feed2385adcb5b2fdda722560c.png)
参数1:父窗口
参数2:标题
参数3:消息文字
返回值:用户点击的按钮,通常只给question类型的窗口使用
示例代码下载链接:https://pan.baidu.com/s/1F5wTeLwn8nm_EwO3iGaUyg
提取码:hqyj
--来自百度网盘超级会员V6的分享
2. 常见窗口类(掌握)
与窗口相关类的继承关系如下。
![](https://img-blog.csdnimg.cn/img_convert/6d74d5f0fb2d188ceec4c93ac68dc90a.png)
QWidget比较特殊,创建对象时,如果不传递parent参数,就是一个独立窗口;如果传递parent参数,就是parent参数对应的窗口对象中的一个内嵌窗口(组件)。
// 构造函数QWidget::QWidget(QWidget * parent = 0)
QWidget有一些专用于窗口函数。
// 设置窗口状态// 常用参数:// Qt::WindowMinimized 窗口最小化// Qt:: WindowMaximized 窗口最大化// Qt::WindowFullScreen 窗口填充整个屏幕,而且没有边框void QWidget::setWindowState(Qt::WindowStates windowState)
// 设置窗口标记// 参数:不同的窗口标记值,支持叠加,使用|void setWindowFlags(Qt::WindowFlags type)//【例子】无边框+最上层setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);
![](https://img-blog.csdnimg.cn/img_convert/20a3b3a9e35eeac92f6f77f830db6097.png)
QMainWindow是最适合作为主窗口的类型,因为一个应用程序的主窗口往往功能较多,此时QMainWindow拥有菜单栏、工具栏、中心组件和状态栏,适合管理各种功能的摆放。
![](https://img-blog.csdnimg.cn/img_convert/a463c09b43405288939cc0a07b29c57d.png)
QMainWindow的四个组成部分类型分别是:
● QMenuBar 菜单栏
用于折叠各种功能选项,包含QMenu和QAction,如下所示。
![](https://img-blog.csdnimg.cn/img_convert/ac82a4ec5954bd464f2209c4b5a5761c.png)
![](https://img-blog.csdnimg.cn/img_convert/33b9d8afe5e982d4545b88cb3c43767c.png)
QAction是实际触发功能的类型,常用信号有:
![](https://img-blog.csdnimg.cn/img_convert/ce799bed9e0cc10b4c918053ffb33b33.png)
● QToolBar 工具栏
用于快速触发功能选项。
![](https://img-blog.csdnimg.cn/img_convert/3b1102e7da7c2008f431c64106b8f4bb.png)
● QWidget 中心组件
设计软件的的区域。
● QStatusBar 状态栏
用于辅助信息显示,常用函数:
// 显示信息// 参数1:显示的信息内容// 参数2:显示信息的时长,单位毫秒;如果设置为0,则表示持续显示void QStatusBar::showMessage(const QString & message, int timeout = 0) [slot]
// 清空信息void QStatusBar::clearMessage() [slot]
QMainWindow示例代码下载链接:https://pan.baidu.com/s/1mDmFXYw0of-jA6GZf8cuSg
提取码:hqyj
--来自百度网盘超级会员V6的分享
3. parent参数(掌握)
几乎所有Qt类的构造函数都有一个parent参数,实际上parent参数是Qt的一种内存管理机制。
示例代码下载链接:https://pan.baidu.com/s/1IgWKpZD-uE9OqF9umIWQBA
提取码:hqyj
--来自百度网盘超级会员V6的分享
当传递parent参数时,可以不手动delete创建的对象,因为当前创建的对象会跟随父对象一并销毁。当不传递parent参数时,一定要手动delete对象,不然会造成内存泄漏。
4. 自定义窗口类(掌握)
4.1 创建自定义窗口
之前的编程虽然可以开启多个窗口,但是子窗口都是已经存在的类,下面从头创建一个之自定义的窗口类,操作步骤如下:
1. 在Qt Creator中,选中项目名称,鼠标右键,点击“添加新文件”。
2. 在弹出界面中,按照下图所示进行操作。
![](https://img-blog.csdnimg.cn/img_convert/b4db63f0bb0b0a7aa2e5e48742a156a7.png)
3. 在弹出的窗口中,先选择需要的窗口的样式,再点击“下一步”。
![](https://img-blog.csdnimg.cn/img_convert/5fd08d717c3fb6646418621451a11e42.png)
4. 在弹出的窗口中配置类名(不要与已有的类名重复且注意大小写),如下所示。
![](https://img-blog.csdnimg.cn/img_convert/1ce72ba0f5c162fe089681923728ab86.png)
5. 在项目管理界面,直接点击“完成”。可以看到项目中多了一个界面类的文件。
![](https://img-blog.csdnimg.cn/img_convert/5c9ddfa1be2b1a16781efefd5ed23834.png)
示例代码下载链接:https://pan.baidu.com/s/11fHtvobpTdxRH363AibmVQ
提取码:hqyj
--来自百度网盘超级会员V6的分享
4.2 主窗口给子窗口传参
主窗口给子窗口传递参数通常可以直接使用函数调用的方式,在子窗口类中开放一些公有函数,主窗口类中直接调用即可。
示例代码下载链接:https://pan.baidu.com/s/1E3R244ej92fXRglB6iMXZQ
提取码:hqyj
--来自百度网盘超级会员V6的分享
4.3 子窗口个主窗口传参
子窗口给主窗口传递参数不太方便操作,因此可以使用信号槽传递参数。在子窗口中发射带参数的自定义信号,在主窗口的槽函数中接收参数。
示例代码下载链接:https://pan.baidu.com/s/1KjhwcTZhgB70lpx3l7QFpA
提取码:hqyj
--来自百度网盘超级会员V6的分享
5. 事件机制
5.1 事件传递(掌握)
事件机制是Qt的底层机制,以一个具体的事件为例,下图描述了事件在整个计算机中传递的步骤。
![](https://img-blog.csdnimg.cn/img_convert/0d6aa8a8877e0b1b7dea2b91a0e0355e.png)
上图描述的是用户操作经过操作系统内核分发到前台正在运行的应用程序的过程,在应用程序内部也伴随着事件的传递,如下所示。
![](https://img-blog.csdnimg.cn/img_convert/7a997e9d54dacdbc1d09b9e183710632.png)
5.2 事件函数(掌握)
Qt内部事件传递可以通过事件函数检测,本次讲解基于QWidget的事件函数,常见的事件函数如下所示。
// 绘制void QWidget::paintEvent(QPaintEvent * event) [virtual protected] // 大小改变void QWidget::resizeEvent(QResizeEvent * event) [virtual protected] // 鼠标按压void QWidget::mousePressEvent(QMouseEvent * event) [virtual protected]// 鼠标释放void QWidget::mouseReleaseEvent(QMouseEvent * event) [virtual protected]// 鼠标双击void QWidget::mouseDoubleClickEvent(QMouseEvent * event) [virtual protected]// 鼠标移动void QWidget::mouseMoveEvent(QMouseEvent * event) [virtual protected]// 移动void QWidget::moveEvent(QMoveEvent * event) [virtual protected]// 按键按压void QWidget::keyPressEvent(QKeyEvent * event) [virtual protected]// 按键释放void QWidget::keyReleaseEvent(QKeyEvent * event) [virtual protected]// 获取焦点void QWidget::focusInEvent(QFocusEvent * event) [virtual protected]// 失去焦点void QWidget::focusOutEvent(QFocusEvent * event) [virtual protected]// 关闭void QWidget::closeEvent(QCloseEvent * event) [virtual protected]// 鼠标进入void QWidget::enterEvent(QEvent * event) [virtual protected]// 鼠标离开void QWidget::leaveEvent(QEvent * event) [virtual protected]
直接使用事件函数的步骤基本相同,本节以绘制事件与按键按压事件为例进行讲解。
示例代码下载链接:https://pan.baidu.com/s/1Xo9w7fcBaLhTWpBef4RFlw
提取码:hqyj
--来自百度网盘超级会员V6的分享
5.3 事件过滤器(熟悉)
如果要检测子组件的事件传递,直接覆盖子组件的事件函数比较复杂,此时可以在父组件中使用过滤器来实现此功能。
![](https://img-blog.csdnimg.cn/img_convert/09c123bfc3afddb8d827f796c2404ced.png)
事件过滤器支持所有的Qt类型,函数原型如下。
// 参数1:被观察的对象,此处指的是注册了过滤器的对象,如果只有一个对象注册了事件过滤器,则此参数可以不用。// 参数2:拦截的事件对象// 返回值:是否拦截继续传递bool QObject::eventFilter(QObject * watched, QEvent * event) [protected virtual]
【例子】当输入密码时天黑,不输入密码时天亮。
![](https://img-blog.csdnimg.cn/img_convert/768b2fa3c01751eb03829377503b214c.png)
示例代码下载链接:https://pan.baidu.com/s/10wNpRtjkw071IBVUFrFAYg
提取码:hqyj
--来自百度网盘超级会员V6的分享