# qt_study **Repository Path**: yanhai307/qt_study ## Basic Information - **Project Name**: qt_study - **Description**: QT 5.9学习 总结 - **Primary Language**: C++ - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 6 - **Forks**: 1 - **Created**: 2020-04-05 - **Last Updated**: 2025-05-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # qt_study ## 介绍 QT 5.9学习 总结 ## 环境 ### Windows 操作系统:Windows10 QT版本:5.9.9,安装路径`D:\Qt\Qt5.9.9` IDE:CLion 2019.3 编译: Toolchains: MinGW - environment: `D:\Qt\Qt5.9.9\Tools\mingw530_32` 编译:CLion CMake options中设置为 -DCMAKE_PREFIX_PATH="D:/Qt/Qt5.9.9/5.9.9/mingw53_32" ### MacOS 操作系统:MacOS 10.14.6 QT版本:5.9.9,安装路径`/Users/yanhai/Qt5.9.9` IDE:CLion 2019.3 编译:CLion CMake options中设置为 -DCMAKE_PREFIX_PATH=/Users/yanhai/Qt5.9.9/5.9.9/clang_64 -DQT_QMAKE_EXECUTABLE=/Users/yanhai/Qt5.9.9/5.9.9/clang_64/bin/qmake ## 示例简介 ### dm01_HelloWorld 演示一个最简单的窗口 知识点: - `QApplication` 应用程序对象,有且仅有一个, 调用对象 `a.exec()` 方法,让应用程序对象进入消息循环机制中,代码阻塞到当前行 - `QWidget` 窗口类,可以调用对象 `w.show()` 方法 显示窗口 - 自定义`Widget`继承自`QWidget`类 - 介绍`qmake`工程文件(`xxx.pro`文件)的内容 ### dm02_QPushButton `QPushButton`按钮类的使用 知识点: - `QPushButton`相关设置 + 对象创建(可以在创建时指定内容及Parent) + 设置Parent:`setParent(Parent对象指针)` + 设置显示内容:`setText("文本内容")` + 设置大小:`resize(宽度, 高度)` + 设置坐标:`move(x, y)` - 自定义按钮类`MyPushButton`,继承`QPushButton`类 - `QWidget`相关设置 + 设置大小:`resize(宽度,高度)` + 设置固定大小:`setFixedSize(宽度,高度)` + 设置窗口标题:`setWindowTitle("标题内容")` - 信号和槽:使用`connect(信号的发送者,发送的具体信号,信号的接收者,信号的处理(槽))`函数将信号和槽绑定 - 对象树:当创建的对象在堆区时候,如果指定的父亲是QObject的派生类,该对象会被放入对象树中,不用管理释放的操作。 ### dm03_SignalAndSlot 自定义信号和槽,及其触发 案例:下课后,老师触发饿了信号,学生响应信号,请客吃饭 知识点: - 自定义信号: + 写到`signals`下 + 返回值是`void`, 只需要声明,不需要实现 + 可以有参数,可以重载 - 自定义槽: + 起Qt版本,槽函数必须写到`public slots`下,高级版本可以写到`public`下或者全局下 + 返回值`void`,需要声明,也需要实现 + 可以有参数,可以发生重载 - 触发信号:使用`emit 信号函数`触发信号 ### dm04_SignalAndSlot2 信号和槽函数出现重载时,如何连接`connect` 知识点: - 当自定义信号和槽出现重载时: + 需要利用函数指针 明确指向函数的地址 + `void (Teacher::*teacherSignal)(QString) = &Teacher::hungry;` - `QString`转成`char *`: + 先通过 `.toUtf8()` 转为 `QByteArray` 类型 + 再通过 `.data()` 转为 `char *` 类型 ### dm05_SignalAndSlot3 信号连接信号、使用lambda表达式实现槽函数 知识点: - 信号可以连接信号 - 拓展: + 一个信号可以连接多个槽函数 + 多个信号可以连接同一个槽函数 + 信号和槽函数的参数 必须类型一一对应 + 信号和槽函数的参数的个数必须要一致吗?信号的参数个数 可以多于槽函数的参数个数 + 可以使用`disconnect`断开信号(参数与`connect`完全相同) - QT4版本以前的信号和槽连接方式 + `connect(zt, SIGNAL(hungry()), st, SLOT(treat()));` + 优点:参数直观 + 缺点:类型不做检测(编译时通过,运行时报错) - 使用lambda表达式实现槽函数 ### dm06_QMainWindow 介绍`QMainWindow`中的`菜单栏`、`工具栏`、`状态栏`、`铆接部件`、`核心部件` 知识点: - 菜单栏:最多只能有一个 + 创建:`QMenuBar *bar = menuBar();` + 添加到窗口:`setMenuBar(bar);` + 创建菜单:`QMenu *fileMenu = bar->addMenu("文件")` + 创建菜单项:`QAction *newAction = fileMenu->addAction("新建");` + 添加分割线:`fileMenu->addSeparator();` - 工具栏:可以有多个 + 创建:`QToolBar *toolBar = new QToolBar(this);` + 添加到窗口:`addToolBar(默认停靠区域, toolBar);` 上方`Qt::TopToolBarArea` + 设置 后期停靠区域`setAllowedAreas`,设置浮动`setFloatable`,设置移动`setMovable` + 添加菜单项`addAction`, 添加控件`addWidget` - 状态栏:最多只能有一个 + 创建:`QStatusBar *stBar = statusBar();` + 添加到窗口:`setStatusBar(stBar);` + 左侧添加控件:`stBar->addWidget(label);` + 右侧添加控件:`stBar->addPermanentWidget(label2);` - 铆接部件(浮动窗口):可以有多个 + 创建:`QDockWidget *dockWidget = new QDockWidget("浮动窗口",this);` + 添加到窗口:`addDockWidget(默认停靠区域, dockWidget);`,下方`Qt::BottomDockWidgetArea` + 设置 后期停靠区域:`setAllowedAreas` - 核心部件:最多只能有一个 + 创建:`QTextEdit *edit = new QTextEdit(this);` + 添加到窗口:`setCentralWidget(edit);` ### dm07_Source 添加资源文件 知识点: - 将图片文件 拷贝到项目位置下 - 右键项目 -> 添加新文件 -> Qt -> Qt Recource File -> 给资源文件起名 - res 生成 res.qrc, 文件右键 `Open in Editor`编辑资源文件 - 添加前缀 添加文件 - 代码中 使用 ":+前缀名+文件名" 方式使用资源文件 ### dm08_QDialog 介绍对话框中的模态对话框和非模态对话框 知识点: - 模态对话框:不可以对其他窗口进行操作 阻塞 + 创建:`QDialog dlg(this);` + 设置大小:`dlg.resize(200, 100);` + 弹出对话框:`dlg.exec();` - 非模态对话框:可以对其他窗口进行操作 + 防止一闪而过 创建到堆区 + 创建:`QDialog *dlg3 = new QDialog(this);` + 为了在关闭对话框时就释放内存 而设置属性:`dlg3->setAttribute(Qt::WA_DeleteOnClose);` + 弹出对话框:`dlg3->show();` ### dm09_QDialog2 介绍一些常用的标准对话框 知识点: - 消息对话框 + QMessageBox 静态成员函数 创建对话框 + 包含 错误、信息、提问、告警 + 参数1:父亲,参数2:标题,参数3:显示内容,参数4:按键类型,参数5:默认关联回车按键 + 返回值:也是StandardButton类型,利用返回值判断用户的输入 - 颜色对话框 QColorDialog::getColor - 文件对话框 QFileDialog::getOpenFileName(父亲,标题,默认路径,过滤文件格式) - 字体对话框 QFontDialog::getFont ### dm10_layout 界面布局 知识点: - 实现登录窗口 - 利用布局方式给窗口进行美化 - 选取widget进行布局,水平布局、垂直布局、栅格布局 - 给用户名、密码标签进行布局,给登录、退出按钮进行布局 - 默认窗口与控件之间有一定的间隙,可以调整layoutLeftMargin - 利用弹簧进行布局 ### dm11_Control 控件介绍 知识点: - 按钮组 + pushButton 常用按钮 + toolButton 工具按钮 用于显示图片,如想显示文字,修改风格:toolButtonStyle,凸起风格 autoRaise + radioButton 单选按钮,通常使用`Group Box`进行分组;设置默认选中 `ui->rBtnMan->setChecked(true);` + checkBox 多选按钮,监听状态,2-选中,1-半选,0-未选中 - QListWidget 列表容器 + 每一行内容都是一个 `QListWidgetItem *item = new QListWidgetItem("锄禾日当午");` + 添加一行 `ui->listWidget->addItem(item);` + 设置居中格式 `item->setTextAlignment(Qt::AlignHCenter);` - QTreeWidget 树控件 + 设置头 `ui->treeWidget->setHeaderLabels(QStringList() << "英雄" << "英雄介绍");` + 创建根节点 `QTreeWidgetItem *item1 = new QTreeWidgetItem(QStringList() << "力量");` + 添加根节点到树控件上 `ui->treeWidget->addTopLevelItem(item1);` + 创建子节点 `QTreeWidgetItem *item1_1 = new QTreeWidgetItem(QStringList() << "刚被猪" << "前排坦克,能在吸收伤害的同时造成可观的范围输出");` + 添加子节点 `item1->addChild(item1_1);` - QTableWidget 表格控件 + 设置列数 `ui->tableWidget->setColumnCount(3);` + 设置水平表头 `ui->tableWidget->setHorizontalHeaderLabels(QStringList() << "姓名" << "性别" << "年龄");` + 设置行数 `ui->tableWidget->setRowCount(5);` + 设置正文 `ui->tableWidget->setItem(0,0, new QTableWidgetItem("亚瑟"));` ### dm12_Control 其他常用控件介绍 知识点: - Scroll Area:自动滚动区 - Tool Box:抽屉控件,可以展开(就像QQ好友的分组) - Tab Widget:选项卡控件 - Stacked Widget:栈控件 + 切换:`ui->stackedWidget->setCurrentIndex(0);` - Combo Box:下拉框 + 添加:`ui->comboBox->addItem("宝马");` - Font Combo Box:字体下拉框 - Line Edit:单行输入框 + 设置为密码模式:设置`echoMode`为`Password` - Text Edit: 富文本输入框 - Plain Text Edit:纯文本输入框 - Spin Box:数字设定框,用于数字的输入 - Double Spin Box:浮点数数字设定框,输入浮点数 - Time Edit:时间 - Date Edit:日期 - Date/Time Edit:日期和时间 - Horizontal Scroll Bar:水平滚动条 - Vertical Scroll Bar:垂直滚动条 - Horizontal Slider:水平滑块 - Vertical Slider:垂直滑块 - Label:显示文件或图片资源(包含动态图片gif) + 显示动态图片:`ui->lbl_Movie->setMovie(movie);` + 播放动图:`movie->start();` ### dm13_SmallWidget 自定义控件封装:将`Spin Box`和`Horizontal Slider`组合进行联动 知识点: - 添加新文件:Qt->设计师界面类(包含.cpp .h .ui) - .ui文件中设计`QSpin Box`和`QSlider`两个控件 - Widget中使用自定义控件 + 拖拽一个Widget控件 + 右键控件点击提升为,提升为SmallWidget,点击添加,点击提升 - 在SmallWidget中实现功能 + 改变数字,滑动条跟着移动 `connect(ui->spinBox, static_cast(&QSpinBox::valueChanged), ui->horizontalSlider, &QSlider::setValue);` + 滑动QSlider,QSpinBox数字跟着改变 `connect(ui->horizontalSlider, &QSlider::valueChanged, ui->spinBox, &QSpinBox::setValue);` + 提供对外的getNum和setNum接口 - 在Widget中测试SmallWidget中提供的接口 ### dm14_QEvent Qt中的事件 知识点: - 鼠标事件 + 进入事件 `virtual void enterEvent(QEvent *event);` + 离开事件 `virtual void leaveEvent(QEvent *event);` + 按下事件 `virtual void mousePressEvent(QMouseEvent *ev);` + 释放事件 `virtual void mouseReleaseEvent(QMouseEvent *ev);` + 移动事件 `virtual void mouseMoveEvent(QMouseEvent *ev);` + 鼠标位置 x坐标 `ev->x()` y坐标`ev->y()` + 判断左右键 `ev->button()` 左键 `Qt::LeftButton` 右键 `Qt::RightButton` + 判断组合按键 `ev->buttons()` 移动事件move的时候用&判断 + 设置鼠标状态追踪 `setMouseTracking(true);` - 格式化字符串 `QString("%1 %2").arg("111").arg("222")` ### dm15_QTimerEvent Qt中的定时器 知识点: - 方式1:利用事件 + 重写定时器方法 `virtual void timerEvent(QTimerEvent *e);` + 启动定时器 `startTimer(1000);` 单位是毫秒 + startTimer的返回值是定时器的唯一标识,可以和e->timerId() 做比较,来确定是哪个定时器触发的 - 方式2:利用定时器类QTimer + 创建定时器类 `QTimer *timer = new QTimer(this);` + 启动定时器 `timer->start(毫秒);` + 到达定时时间,发送信号 QTimer::timeout + 暂停按钮 `timer->stop();` ### dm16_QEvent2 Qt事件分发器和过滤器:event和eventFilter 知识点: - 事件分发器: + 用途:用于事件的分发 + 也可以做拦截操作,不建议 + `bool event(QEvent *e);` + 返回值 如果是true代表用户处理这个事件,不向下分发了 + `e->type()`事件的类型 - 事件过滤器: + 在程序将事件分发到事件分发器之前,可以利用过滤器做拦截 + 安装事件过滤器 `ui->label->installEventFilter(this);` + 重写eventFilter函数 `bool eventFilter(QObject *obj, QEvent *e);` ### dm17_QPainter QPainter 绘图 知识点: - 绘图事件 `void paintEvent(QPaintEvent *);` - 声明一个画家对象 `QPainter painter(this);` this表示绘图设备,代表当前窗口 - 设置画笔 + 创建画笔 `QPen pen(QColor(255, 0, 0));` + 设置风格 `pen.setStyle(Qt::DotLine);` + 设置宽度 `pen.setWidth(3);` - 让画家使用画笔 `painter.setPen(pen);` - 设置画刷 + 创建画刷 `QBrush brush(Qt::cyan);` + 设置风格 `brush.setStyle(Qt::Dense7Pattern);` - 让画家使用画刷 `painter.setBrush(brush);` - 画线、画圆、画矩形、画文字 + 画线 `painter.drawLine(QPoint(0, 0), QPoint(100, 100));` + 画圆 `painter.drawEllipse(QPoint(100, 100), 50, 50);` + 画矩形 `painter.drawRect(QRect(20, 20, 50, 50));` + 画文字 `painter.drawText(QRect(10, 200, 150, 50), "好好学习,天天向上");` ### dm18_QPainter2 QPainter 绘图 - 高级设置 知识点: - 设置抗锯齿能力,效率低 `painter.setRenderHint(QPainter::Antialiasing);` - 对画家进行移动 `painter.translate(100, 0);` 表示向右移动100 - 保存画家状态 `painter.save();` - 还原画家状态 `painter.restore();` - 绘制图片资源 `painter.drawPixmap(posX, 200, QPixmap(":/Image/Cii11.png"));` - 手动调用绘图事件 调用`update()` ### dm19_QPaintDevice 绘图设备,是继承了QPainterDevice的子类,Qt一共提供了四个这样的类,分别为QPixmap QBitmap QImage QPicture 知识点: - `QPixmap`:对不同平台做了优化 - `QPixmap pix(300, 300);` 定义绘图设备的宽和高 - `pix.fill(Qt::white);` 填充颜色(背景色) - `QPainter painter(&pix);` 利用画家往pix上画画 - `pix.save("D:\\pix.png");` 保存 - `QImage`:可以对像素进行访问,使用和QPixmap差不多,只有定义的时候不同 - `QImage img(300, 300, QImage::Format_RGB32);` - `img.setPixel(i, j, qRgb(255, 0, 0));` 修改像素 - `QBitmap`:是QPixmap的子类,它的色深限定为1(黑白色)。 - 可以使用Qpixmap的isQBitmap()函数来确定这个QPixmap是不是一个QBitmap - `QPicture`:记录和重现绘图指令 - `QPicture pic;` - `painter.begin(&pic);` 开始往pic上画 - `painter.end();` 结束画画 - `pic.save(任意后缀);` 保存 - `pic.load(文件路径);` 加载 - `painter.drawPicture(0, 0, pic);` 利用画家重现 - `QWidget` ### dm20_QFile 使用QFile对文件进行读写操作 知识点: - `QFile file(文件路径);` - 读操作 - `file.open(QIODevice::ReadOnly)` 只读模式打开文件 - `file.readAll()` 全部读取 - `file.readLine()` 按行读取 - `file.atEnd()` 判断是否读到文件尾 - 默认编码格式为utf-8 - 可以利用编码格式类 转换格式 - `QTextCodec *codec = QTextCodec::codecForName("gbk");` - `ui->textEdit->setText(codec->toUnicode(array));` - 写操作 - `file.open(QIODevice::Append / WriteOnly)` - `file.write(内容)` - `file.close()` 关闭文件 ### dm21_QFileInfo 使用QFileInfo读取文件信息 知识点: - `QFileInfo info(文件路径)` - `info.size()` 文件大小 - `info.suffix()` 文件后缀 - `info.fileName()` 文件名称 - `info.filePath()` 文件路径 - `info.created()` 创建时间,QDateTime类型 - `info.lastModified()` 最后修改时间,QDateTime类型 - QDateTime类型 - `toString("格式方式")`, 如`yyyy/MM/dd hh:mm:ss` ### case02_CoinFlip 项目2-翻金币 知识点: - 创建项目、添加项目资源 - 基本配置 - 设置程序图标 - 设置固定大小 - 设置项目标题 - 设置背景 - 设置背景标题 - 开始菜单-退出功能 - 创建开始按钮 - 封装自定义按钮 MyPushButton - 构造函数(默认显示图片,按下后显示的图片) - 测试开始按钮 - 开始制作特效 - zoom1 向下弹跳 - zoom2 向上弹跳 - 创建选择关卡场景 - 点击开始按钮后 延时进入 选择关卡场景 - 配置选择关卡场景(图标,标题,大小) - 设置背景图片,设置标题图片 - 创建返回按钮 - 选择关卡的返回按钮特效制作 - 点击后切换为另一个图片 - 重写 void mousePressEvent - 重写 void mouseReleaseEvent - 开始场景与选择关卡场景的切换 - 点击选择关卡场景的返回按钮,发送一个自定义信号 - 在主场景中监听这个信号,并且当触发信号后,重新显示主场景,隐藏掉选择关卡的场景 - xx