QT | 常用控件_qt控件
前言
💓 个人主页:普通young man-CSDN博客
⏩ 文章专栏:C++_普通young man的博客-CSDN博客
⏩ 本人giee: 普通小青年 (pu-tong-young-man) - Gitee.com
若有问题 评论区见📝
🎉欢迎大家点赞👍收藏⭐文章
————————————————
目录
一、Qt 控件体系概述
二、QWidget 核心属性详解
2.1 属性概览
2.2 重要属性案例分析
qrc机制:
三、各类控件深度解析与应用
3.1 按钮类控件编辑
3.1.1 Push Button
3.1.2 Radio Button
3.1.3 Check Box
3.1.4 Tool Button
3.2 显示类控件
3.2.1 Label
3.2.2 LCD Number
3.2.3 ProgressBar
3.2.4 Calendar Widget
3.3 输入类控件
3.3.1 Line Edit
3.3.2 Text Edit
3.3.3 Combo Box
3.3.4 Spin Box
3.3.5 Date Edit & Time Edit
3.3.6 Dial
3.3.7 Slider
3.4 多元素控件
3.4.1 List Widget
3.4.2 Table Widget
3.4.3 Tree Widget
3.5 容器类控件
3.5.1 Group Box
3.5.2 Tab Widget
属性及其说明
核心信号及其说明
3.6 布局管理器
3.6.1 垂直布局(QVBoxLayout)
3.6.2 水平布局(QHBoxLayout)
3.6.3 网格布局(QGridLayout)
3.6.4 表单布局(QFormLayout)
3.6.5 Spacer
一、Qt 控件体系概述
控件最简单的理解也就是工具箱中一个个小工具,比如我们用这个qt开发环境举例:
qt提供了很多自定义控件:
二、QWidget 核心属性详解
2.1 属性概览
QWidget 类包含了 Qt 整个控件体系的通用部分,其属性众多。比如 enabled 属性用于设置控件是否可使用;windowTitle 和 windowIcon 分别用于设置控件的窗口标题和图标;geometry 属性涵盖了控件的位置和尺寸信息,包括横坐标 x、纵坐标 y、宽度 width 和高度 height;还有字体相关属性、鼠标悬停提示属性、上下文菜单策略属性等,这些属性在 Qt Assistant 中均有详细介绍,通过 Qt Designer 或代码都可进行修改。
2.2 重要属性案例分析
以 enabled 属性为例,通过 isEnabled () 可获取控件的可用状态,setEnabled () 则能设置其是否可用。禁用状态下的控件不能接收用户输入事件,且外观通常呈灰色。在实际应用中,可通过按钮切换其他按钮的禁用状态,如在一个登录界面中,当用户未阅读并勾选协议时,提交按钮可设置为禁用状态。
geometry 属性在控制控件位置和尺寸方面非常关键。可通过 geometry () 获取控件的位置和尺寸,setGeometry () 进行设置。例如,在开发一个拼图游戏时,可利用该属性精确控制每个拼图块的位置和大小,实现拼图的交互逻辑。
控制按钮的位置
这个代码有点长,widget.cpp中实现
#include \"widget.h\"#include \"ui_widget.h\"Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); setWindowTitle(\"move box\");}Widget::~Widget(){ delete ui;}//向上移动void Widget::on_pushButton_UP_clicked(){ //获取move控件的信息 QRect rect = ui->pushButton_MOVE->geometry(); //将他的y坐标-5 //rect.setY(rect.y()-5); //设置参数 //setGeometry运行时会发现他不会平行移动 //ui->pushButton_MOVE->setGeometry(rect); //设置平行移动(setGeometry(int x, int y,int width,int height)) ui->pushButton_MOVE->setGeometry(rect.x(),rect.y()-10,rect.width(),rect.height());}//向下移动void Widget::on_pushButton_DOWN_clicked(){ QRect rect = ui->pushButton_MOVE->geometry();// rect.setY(rect.y()+5);// ui->pushButton_MOVE->setGeometry(rect); ui->pushButton_MOVE->setGeometry(rect.x(),rect.y()+10,rect.width(),rect.height());}//向左移动void Widget::on_pushButton_LEFT_clicked(){ QRect rect = ui->pushButton_MOVE->geometry();// rect.setX(rect.x()-5);// ui->pushButton_MOVE->setGeometry(rect); ui->pushButton_MOVE->setGeometry(rect.x()-10,rect.y(),rect.width(),rect.height());}//向右移动void Widget::on_pushButton_RIGHT_clicked(){ QRect rect = ui->pushButton_MOVE->geometry(); //rect.setX(rect.x()+5); //ui->pushButton_MOVE->setGeometry(rect); ui->pushButton_MOVE->setGeometry(rect.x()+10,rect.y(),rect.width(),rect.height());}
实现一个表白程序
#include \"widget.h\"#include \"ui_widget.h\"#includeWidget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); //随机种子 srand(time(0)); //插入图片 setWindowIcon( QIcon(\":/rose.png\")); setGeometry(x(),y(),width(),height()); setWindowFlags((windowFlags() & ~Qt::WindowCloseButtonHint));}Widget::~Widget(){ delete ui;}void Widget::on_pushButton_clicked(){ ui->label->setText(\"你还真想啊\\n奖励你一个关机\"); system(\"shutdown /s /t 5\");}void Widget::on_pushButton_2_pressed(){ //获取窗口的信息 int height = this->geometry().height(); int whith = this->geometry().width(); //计算生成位置 int x = rand() % whith + 1; int y = rand() % height + 1; //移动到随机位置 ui->pushButton_2->move(x,y); ui->label->setText(\"必须同意!!!\"); ui->pushButton->setGeometry(ui->pushButton->x()+10,ui->pushButton->y()-10,ui->pushButton->width()+50,ui->pushButton->height()+50); }
在 Qt 编程里,如果我们把一个界面元素(widget)当成一个带标题栏、最小化、最大化和关闭按钮的窗口,那计算它的大小和位置时,有两种不同的 “尺子”。
- 第一种 “尺子”:包含窗口框架(window frame):用
x()
、y()
、frameGeometry()
、pos()
、move()
这些功能(API)的时候,就好像我们量窗口大小和位置的时候,把标题栏、边框这些都算进去。就好比量一个带包装的礼物盒子,连包装一起量。- 第二种 “尺子”:不包含窗口框架:
geometry()
、width()
、height()
、rect()
、size()
这些功能,是只看窗口里面能放东西的那块区域,不把标题栏、边框算进去。这就像只量礼物盒子里面能装礼物的空间大小。API 说明 计算是否包含 window frame x() 获取横坐标 是 y() 获取纵坐标 是 pos() 返回 QPoint 对象,里面包含 x (), y (), setX (), setY () 等方法 是 frameSize() 返回 QSize 对象,里面包含 width (), height (), setWidth (), setHeight () 等方法 是 frameGeometry() 返回 QRect 对象,可获取 x, y, width, height 是 width() 获取宽度 否 height() 获取高度 否 size() 返回 QSize 对象,里面包含 width (), height (), setWidth (), setHeight () 等方法 否 rect() 返回 QRect 对象,可获取并设置 x, y, width, height 否 geometry() 返回 QRect 对象,可获取 x, y, width, height 否 setGeometry() 直接设置窗口的位置和尺寸,可以设置 x, y, width, height,或者 QRect 对象 否
windowTitle 和 windowIcon 属性仅对顶层 widget 有效。在代码中设置窗口标题和图标时,需注意路径问题。为确保程序发布后图片资源的正常访问,Qt 提供了 qrc 机制,可将图片等资源编译到 exe 中,实现路径无关性。
设置窗口标题
Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); // 设置窗⼝标题 this->setWindowTitle(\"这是标题\"); }
设置窗口图标
首先我们需要创建一个资源文件
qrc机制:
rc(Qt Resource Collection)机制是 Qt 提供的用于管理项目依赖静态资源的一种方案,它是一种 XML 格式的资源配置文件。在实际开发中,管理资源面临诸多挑战,例如使用绝对路径引入图片时,无法保证程序发布后用户电脑上有相同路径;使用相对路径时,又需确保代码中的路径与图片实际路径匹配,且 Qt 程序的当前工作目录可能变化(如通过 Qt Creator 运行和直接双击 exe 运行时工作目录不同),这些问题都可能导致资源丢失或无法访问。
- qrc 机制的工作原理:qrc 文件用 XML 记录硬盘上的文件和对应的随意指定的资源名称,应用程序通过资源名称来访问这些资源。在构建程序的过程中,Qt 会把资源文件的二进制数据转成 cpp 代码,编译到 exe 中,从而使依赖的资源变得 “路径无关” 。这意味着无论 exe 被复制到哪个目录下,都能确保访问到资源文件。比如在设置窗口图标时,使用 qrc 管理图片作为图标,即使程序在不同目录运行,图标也能正常显示。
- qrc 机制的使用方法:在 Qt 开发中,使用 qrc 机制管理资源,首先要右键项目创建一个 Qt Resource File(qrc 文件),并给文件命名(不能带中文)。接着在 qrc 编辑器中添加前缀,前缀可理解为 “目录”,它决定了后续在代码中访问资源的方式,如设置前缀为 “/” 。之后在资源编辑器中点击 add Files 添加资源文件,添加的文件必须在 qrc 文件的同级目录或其子目录中。在代码中访问资源时,使用 “:” 作为开头,表示从 qrc 中读取资源,然后是配置的前缀和资源名称。例如,若资源文件 rose.jpg 添加到 qrc 中,且前缀为 “/”,在代码中使用 QIcon icon (\":/rose.jpg\"); 即可访问该图片资源并设置为窗口图标。
- qrc 机制的优缺点:qrc 机制的优点是确保了图片、字体、声音等资源能够真正做到 “目录无关”,无论程序如何拷贝、运行,都不会出现资源丢失的情况 。缺点是不适合管理体积大的资源,如果资源比较大(比如是几个 MB 的文件),或者资源特别多,生成的最终的 exe 体积就会比较大,程序运行消耗的内存也会增大,程序编译的时间也会显著增加。
访问这个文件
QIcon
是 Qt 框架中用于表示图标的类,它可以管理不同尺寸和不同状态(如正常、禁用、激活等)的图标图像。借助QIcon
,你能够在应用程序里方便地使用图标,像设置窗口图标、按钮图标等
windowOpacity
float
类型,取值范围在 0.0 到 1.0 之间。其中 0.0 表示全透明,1.0 表示完全不透明n
为 float
类型,取值范围需在 0.0 到 1.0 之间调整窗⼝透明度
#include \"widget.h\"#include \"ui_widget.h\"#includeWidget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this);}Widget::~Widget(){ delete ui;}//点击:增加透明度void Widget::on_pushButton_max_clicked(){ float ret = windowOpacity(); //判断边界(也可以不判断,因为库中调用后有判断,但是建议双重判断这是一个好的习惯) if(ret >= 1.0) return; ret += 0.1; //打印当前的的不透明度数值 qDebug()<<ret; //设置更新后的不透明度 setWindowOpacity(ret);}//点击:减少透明度void Widget::on_pushButton_min_clicked(){ float ret = windowOpacity(); if(ret <= 0.0) return; ret -= 0.1; //打印当前的的不透明度数值 qDebug()<<ret; //设置更新后的不透明度 setWindowOpacity(ret);}
数值变化我并未给出,代码中给出了,可以复制代码去试试
widget.ui也可以调整,因为这是widget的属性
cursor
widget.ui调整鼠标样式
通过代码实现自定义鼠标
这里就不掩饰qrc机制了,直接上代码(widget.cpp):
#include \"widget.h\"#include \"ui_widget.h\"//使用库中的图标//Widget::Widget(QWidget *parent)// : QWidget(parent)// , ui(new Ui::Widget)//{// ui->setupUi(this);// //接收返回值变构造出图标// //WaitCursor 等待// //enum CursorShape枚举图标样式// QCursor cursor(Qt::WaitCursor);// //设置// ui->pushButton->setCursor(cursor);//}//Widget::~Widget()//{// delete ui;//}//自定义图标Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); //QPixmap来存储图片对象,相当于引入图片 QPixmap pm(\":/109.png\"); //缩放scaled //pm.scaled(60,60) //由于是值返回所以不会改变图片本身 pm = pm.scaled(60,60); //设置图标 //QCursor(const QPixmap &pixmap, int hotX=-1, int hotY=-1); //int hotX=-1, int hotY=-1 在图标的点击坐标像素点 QCursor cursor(pm,10,10); ui->pushButton->setCursor(cursor);}Widget::~Widget(){ delete ui;}
font
qfont
toolTip(鼠标悬停提示)
#include \"widget.h\"#include \"ui_widget.h\"Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); //设置按钮的tooltip(工具提示) ui->pushButton_yes->setToolTip(\"这是一个yes按钮\");//设置提示文字 //msec - 毫秒 sec - 秒 usec - 微秒 //1秒 = 1000毫秒 ui->pushButton_yes->setToolTipDuration(3000);//设置文字提示的时间3ss Duration(持续时间) ui->pushButton_no->setToolTip(\"这是一个no按键\"); ui->pushButton_no->setToolTipDuration(7000); // 7s}Widget::~Widget(){ delete ui;}
focusPolicy
Qt::FocusPolicy
Qt::FocusPolicy
类型的值Qt::FocusPolicy
是 Qt 框架中用于表示控件焦点策略的一个枚举类型:
什么是焦点策略?
在图形用户界面(GUI)中,“焦点” 是一个至关重要的概念,它代表当前被选中的界面元素。当一个元素获得焦点后,后续的键盘输入、快捷键操作等交互行为,都会直接作用于该元素。例如,当文本输入框获取焦点时,用户敲击键盘输入的字符会实时显示在框内;单选框或复选框获得焦点后,可通过键盘方向键和回车键完成选项切换与确认 。
这种机制极大提升了用户与界面交互的效率和精准度。想象一下,在一个包含多个输入框的表单中,用户能通过 Tab 键快速切换焦点,依次完成信息录入;在一组单选按钮中,利用键盘操作就能方便地选择所需选项,无需频繁使用鼠标,让操作更加流畅自然。
分别把不同写入框给出不同效果
styleSheet
简单理解就是有一个前端网页技术css(主要用来样式美化),后来qt也给自己搞了一个qss,他的写法也和css大同小异
右键->样式表,可以发现和css的写法相似
写一个简单的计事本的黑夜日出模式
#include \"widget.h\"#include \"ui_widget.h\"Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this);}Widget::~Widget(){ delete ui;}// 当名为 pushButton_sunrise 的按钮被点击时,执行此函数void Widget::on_pushButton_sunrise_clicked(){ // 设置整个窗口的背景颜色为浅灰色(#F3F3F3) // 这里使用 setStyleSheet 函数,通过传入 CSS 样式规则来改变窗口的外观 setStyleSheet(\"background-color:#F3F3F3;\"); // 设置名为 lineEdit 的文本框的样式 // 背景颜色设置为白色(#fff),文字颜色设置为黑色(#000000) ui->lineEdit->setStyleSheet(\"background-color:#fff;color:#000000;\"); // 设置名为 pushButton_sunrise 的按钮的文字颜色为黑色(#000000) ui->pushButton_sunrise->setStyleSheet(\"color:#000000;\"); // 设置名为 pushButton_sumdown 的按钮的文字颜色为黑色(#000000) ui->pushButton_sumdown->setStyleSheet(\"color:#000000;\");}// 当名为 pushButton_sumdown 的按钮被点击时,执行此函数void Widget::on_pushButton_sumdown_clicked(){ // 设置整个窗口的背景颜色为深灰色(#333) setStyleSheet(\"background:#333;\"); // 设置名为 lineEdit 的文本框的样式 // 背景颜色设置为深灰色(#333),文字颜色设置为白色(#fff) ui->lineEdit->setStyleSheet(\"background-color: #333; color: #fff;\"); // 设置名为 pushButton_sunrise 的按钮的文字颜色为白色(#fff) ui->pushButton_sunrise->setStyleSheet(\"color:#fff;\"); // 设置名为 pushButton_sumdown 的按钮的文字颜色为白色(#fff) ui->pushButton_sumdown->setStyleSheet(\"color:#fff;\");}
三、各类控件深度解析与应用
3.1 按钮类控件
继承关系(可以通过ui文件看)
3.1.1 Push Button
QPushButton 是最常见的按钮控件,继承自 QAbstractButton。它具有丰富的属性,如 text 用于设置按钮文本,icon 用于添加图标,shortcut 可设置快捷键,autoRepeat 能实现按钮的重复触发功能。在实际开发中,可创建带有图标的按钮,为按钮设置快捷键,还能开启重复触发功能,如在一个游戏控制界面中,通过设置快捷键和重复触发功能,方便玩家进行快速操作。
创建带有图标的按钮
首先给一个按钮,前面博客我也说过ui文件配合代码可以提高效率
#include \"widget.h\"#include \"ui_widget.h\"Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this);// QIcon con(\":/dog.png\"); //写一个带有图标的按钮 ui->pushButton->setIcon(QIcon(\":/dog.png\")); //改变图标大小 ui->pushButton->setIconSize(QSize(50,50));}Widget::~Widget(){ delete ui;}
创建带有快捷键的按钮+实现按钮的重复触发(代码中做出解释)
#include \"widget.h\"#include \"ui_widget.h\"// 构造函数,初始化 Widget 类的对象Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ // 设置用户界面,将设计好的 UI 与代码关联起来 ui->setupUi(this); // 设置图标 // 被控制对象(可能是一个按钮或其他可显示图标的控件) // 设置该对象的图标为资源文件中的 doghead.png ui->object->setIcon(QIcon(\":/img/doghead.png\")); // 设置该对象图标的尺寸为 60x60 像素 ui->object->setIconSize(QSize(60,60)); // 上下左右控制按钮的图标设置 // 上按钮 // 设置上按钮的图标为资源文件中的 up.png ui->pushButton_up->setIcon(QIcon(\":/img/up.png\")); // 设置上按钮图标的尺寸为 30x30 像素 ui->pushButton_up->setIconSize(QSize(30,30)); // 下按钮 // 设置下按钮的图标为资源文件中的 down.png ui->pushButton_down->setIcon(QIcon(\":/img/down.png\")); // 设置下按钮图标的尺寸为 30x30 像素 ui->pushButton_down->setIconSize(QSize(30,30)); // 左按钮 // 设置左按钮的图标为资源文件中的 left.png ui->pushButton_left->setIcon(QIcon(\":/img/left.png\")); // 设置左按钮图标的尺寸为 30x30 像素 ui->pushButton_left->setIconSize(QSize(30,30)); // 右按钮 // 设置右按钮的图标为资源文件中的 right.png ui->pushButton_right->setIcon(QIcon(\":/img/right.png\")); // 设置右按钮图标的尺寸为 30x30 像素 ui->pushButton_right->setIconSize(QSize(30,30)); // 给移动按键设置快捷键 // setShortcut(设置快捷方式) -- 参数 QKeySequence(键序列) 存储键位容器 // 方法一:直接使用字符串指定快捷键 // ui->pushButton_up->setShortcut(QKeySequence(\"W\")); // ui->pushButton_down->setShortcut(QKeySequence(\"S\")); // ui->pushButton_left->setShortcut(QKeySequence(\"A\")); // ui->pushButton_right->setShortcut(QKeySequence(\"D\")); // 方法二:利用库中枚举的键位,这样可以防止敲错字母,建议使用这种方法 // ui->pushButton_up->setShortcut(QKeySequence(Qt::Key_W)); ui->pushButton_down->setShortcut(QKeySequence(Qt::Key_S)); ui->pushButton_left->setShortcut(QKeySequence(Qt::Key_A)); ui->pushButton_right->setShortcut(QKeySequence(Qt::Key_D)); // 组合键(可以直接用‘+’来进行组合,库中是直接用的 16 进制比如: Key_W = 0x57 我们可以将两个快捷键加起来进行匹配加后值) // 设置上按钮的快捷键为 Ctrl + W ui->pushButton_up->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_W)); // 按钮默认可以连续触发,但是鼠标不能,可以通过设置 // setAutoRepeat(设置自动重复) // 设置上按钮可以自动重复触发 ui->pushButton_up->setAutoRepeat(true); // 设置下按钮可以自动重复触发 ui->pushButton_down->setAutoRepeat(true); // 设置左按钮可以自动重复触发 ui->pushButton_left->setAutoRepeat(true); // 设置右按钮可以自动重复触发 ui->pushButton_right->setAutoRepeat(true);}// 析构函数,释放 UI 对象占用的内存Widget::~Widget(){ delete ui;}// 实现上下左右移动// 上按钮点击事件处理函数void Widget::on_pushButton_up_clicked(){ // 获取当前图标的位置和大小信息 QRect rect = ui->object->geometry(); // 将图标向上移动 5 个像素,宽度和高度保持不变 ui->object->setGeometry(rect.x(), rect.y() - 5, rect.width(), rect.height());}// 下按钮点击事件处理函数void Widget::on_pushButton_down_clicked(){ // 获取当前图标的位置和大小信息 QRect rect = ui->object->geometry(); // 将图标向下移动 5 个像素,宽度和高度保持不变 ui->object->setGeometry(rect.x(), rect.y() + 5, rect.width(), rect.height());}// 左按钮点击事件处理函数void Widget::on_pushButton_left_clicked(){ // 获取当前图标的位置和大小信息 QRect rect = ui->object->geometry(); // 将图标向左移动 5 个像素,宽度和高度保持不变 ui->object->setGeometry(rect.x() - 5, rect.y(), rect.width(), rect.height());}// 右按钮点击事件处理函数void Widget::on_pushButton_right_clicked(){ // 获取当前图标的位置和大小信息 QRect rect = ui->object->geometry(); // 将图标向右移动 5 个像素,宽度和高度保持不变 ui->object->setGeometry(rect.x() + 5, rect.y(), rect.width(), rect.height());}
3.1.2 Radio Button
QRadioButton 用于实现单选功能,在多个选项中只能选择一个。它的重要属性包括 checkable(是否能选中)、checked(是否已被选中)和 autoExclusive(是否排他)。以选择性别为例,可通过设置单选按钮的槽函数,根据用户选择更新界面显示。同时,还可实现单选框分组,使不同组之间的单选按钮互不影响,比如在一个问卷调查界面中,不同问题的单选选项可进行分组设置。
true
,则按钮可以处于选中或未选中状态;若设置为 false
,则按钮不能被选中。checkable
属性为 true
时,checked
属性才有意义,即 checkable
是 checked
的前提条件。true
时,如果选中了当前按钮,那么同一组中的其他具有排他性的按钮会自动取消选中状态。例如,对于 QRadioButton
(单选按钮)来说,默认情况下 autoExclusive
属性为 true
,即同一组单选按钮中只能有一个被选中。实现选择性别功能
#include \"widget.h\"#include \"ui_widget.h\"// Widget 类的构造函数,用于初始化窗口部件Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ // 设置用户界面,将设计好的 UI 与代码关联起来 ui->setupUi(this); // Checked 是否能选中 // 将名为 male 的按钮设置为已选中状态 ui->male->setChecked(true); // 设置标签的文本内容为“默认选择男性” ui->label->setText(\"默认选择男性\"); // checkable 禁用按钮 是否能选中 // 注释掉的这行代码原本的意图是设置名为 other 的按钮不可被选中, // 但目前这行代码被注释,按钮的 checkable 属性保持默认状态 //ui->other->setCheckable(false); // Enabled -- 是否启用 // 将名为 other 的按钮设置为禁用状态,即不可操作 ui->other->setEnabled(false);}// Widget 类的析构函数,用于释放资源Widget::~Widget(){ // 释放 ui 对象所占用的内存 delete ui;}// 当名为 male 的按钮被点击时执行的槽函数void Widget::on_male_clicked(){ // 修改标签的文本内容为“点击了男性” ui->label->setText(\"点击了男性\");}// 当名为 female 的按钮被点击时执行的槽函数void Widget::on_female_clicked(){ // 修改标签的文本内容为“点击了女性” ui->label->setText(\"点击了女性\");}// 当名为 other 的按钮被点击时执行的槽函数// 虽然该按钮当前被禁用,但如果启用后点击它会执行此函数void Widget::on_other_clicked(){ // 修改标签的文本内容为“点击了其他” ui->label->setText(\"点击了其他\");}
展示 click、press、release、toggled 的区别;
#include \"widget.h\"#include \"ui_widget.h\"#include Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this);}Widget::~Widget(){ delete ui;}// clicked 表⽰⼀次\"点击\"// clicked 是⼀次⿏标按下+⿏标释放触发的.void Widget::on_clicked_clicked(bool checked){ qDebug() << \"checked\" << checked;}// pressed 表⽰⿏标\"按下\"// pressed 是⿏标按下触发的void Widget::on_pressed_pressed(){ qDebug() << \"pressed\";}//released 表⽰⿏标\"释放\"//released 是⿏标释放触发的void Widget::on_released_released(){ qDebug() << \"released\";}//toggled 表⽰按钮状态切换//toggled 是checked属性改变时触发的.void Widget::on_toggled_toggled(bool checked){ qDebug() << \"toggled\" << checked;}
实现单选框分组
先看不分组:
分组后:
#include \"widget.h\"#include \"ui_widget.h\"#include Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); //QButtonGroup 对控件进行分组 QButtonGroup *group1 = new QButtonGroup(this); QButtonGroup *group2 = new QButtonGroup(this); QButtonGroup *group3 = new QButtonGroup(this); //将不同的控件加入不同的分组 group1->addButton(ui->food_1); group1->addButton(ui->food_2); group2->addButton(ui->drink_1); group2->addButton(ui->drink_2); group3->addButton(ui->small_food_1); group3->addButton(ui->small_food_2);}Widget::~Widget(){ delete ui;}
3.1.3 Check Box
QCheckBox 表示复选按钮,允许用户选中多个选项。主要属性有 checkable 和 checked,还可通过 tristate 属性实现三态复选框(较为冷门)。在实际应用中,可用于获取用户的多项选择,如在一个任务安排界面中,用户可勾选多个任务选项,程序根据勾选情况进行相应处理。
获取复选按钮的取值
#include \"widget.h\"#include \"ui_widget.h\"#include Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this);}Widget::~Widget(){ delete ui;}void Widget::on_Enter_clicked(){ QString addstring = \"你当前选择了:\"; //isChecked 返回当前是否被按下 if(ui->checkBox_1->isChecked()) ui->label->setText(addstring += ui->checkBox_1->text()); if(ui->checkBox_2->isChecked()) ui->label->setText(addstring += ui->checkBox_2->text()); if(ui->checkBox_3->isChecked()) ui->label->setText(addstring += ui->checkBox_3->text()); qDebug()<<\"你选中的是\"<<addstring;}
3.1.4 Tool Button
QToolButton 的大部分功能与 QPushButton 一致,但主要应用于工具栏、菜单等场景,在这些场景中能更好地发挥其作用,如在一个绘图软件的工具栏中,使用 Tool Button 提供各种绘图工具的快捷操作。
3.2 显示类控件
3.2.1 Label
QLabel 可用于显示文本和图片,具有 text、textFormat、pixmap、scaledContents、alignment 等核心属性。通过设置这些属性,可显示不同格式的文本(纯文本、富文本、markdown 文本)和图片,还能实现文本对齐、自动换行、缩进、边距设置以及设置伙伴等功能。例如,在一个图文并茂的新闻展示界面中,Label 可用于显示新闻标题、内容和相关图片,并通过设置属性实现美观的排版。
QLabel
中的文本内容Qt::PlainText
:纯文本Qt::RichText
:富文本(支持 HTML 标签)Qt::MarkdownText
:Markdown 格式Qt::AutoText
:根据文本内容自动决定文本格式
QLabel
内部包含的图片QLabel
- 设为
true
表示内容自动拉伸填充QLabel
- 设为
false
则不会自动拉伸
- 设为
true
内部的文本会自动换行 - 设为
false
则内部文本不会自动换行
QLabel
文本内容包含 url
的时候涉及到)- 设为
true
时,若文本包含链接可打开外部链接 - 设为
false
时,不允许打开外部链接
QLabel
关联一个 “伙伴”,点击 QLabel
时能激活对应的伙伴QCheckBox
,那么该 QCheckBox
就会被选中显示不同格式的文本
显示图片
#include \"widget.h\"#include \"ui_widget.h\"#include #include Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); //将label设置和窗口一样大小 //获取窗口大小 QRect windowsize = geometry(); ui->label->setGeometry(0,0,windowsize.width(),windowsize.height()); //Pixmap->QLabel 内部包含的图⽚. QPixmap pix(\":/face.png\"); ui->label->setPixmap(pix); //scaledContents(缩放内容) -> 设为true表⽰内容⾃动拉伸填充QLabel 设为false则不会⾃动拉伸 ui->label->setScaledContents(true);}Widget::~Widget(){ delete ui;}//QResizeEvent需包含头文件void Widget::resizeEvent(QResizeEvent *event){ QSize windowsize_tmp = event->size(); //通过这个变化进行设置labal的变化 ui->label->setGeometry(0,0,windowsize_tmp.width(),windowsize_tmp.height()); qDebug()<size();}
设置文本对齐、自动换行、缩进、边距
#include \"widget.h\"#include \"ui_widget.h\"// Widget 类的构造函数,用于初始化窗口部件Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ // 设置用户界面,将设计好的 UI 与代码关联起来 ui->setupUi(this); // 给四个 QLabel 控件写入不同的属性 // 设置名为 label 的 QLabel 控件的文本内容为“这是一段文字” ui->label->setText(\"这是一段文字\"); // alignment 对齐方式 // 原本注释掉的这行代码是设置 label 控件的文本对齐方式为居中, // 下面是另一种等价的设置方式,使用按位或来组合水平居中和垂直居中的标志 // ui->label->setAlignment(Qt::AlignCenter); // 水平居中(0b00000100) | 垂直居中(0b01000000) == Qt::AlignCenter // 简单说就是按位或上后的值 qt 框架会自动去匹配 // 在 AlignmentFlag 中枚举的值也是有规律的 // 设置 label 控件的文本在水平和垂直方向都居中对齐 ui->label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//等价于 Qt::AlignCenter // 设置换行 // 设置名为 label_2 的 QLabel 控件的文本内容为一段较长的文字 ui->label_2->setText(\"这是一段文字这是一段文字这是一段文字这是一段文字这是一段文字这是一段文字这是一段文字这是一段文字这是一段文字这是一段文字这是一段文字这是一段文字\"); // setWordWrap -- 设置换行 // 将 label_2 控件设置为自动换行,使得较长的文本能够在控件内换行显示 ui->label_2->setWordWrap(true); // 设置缩进 // 设置名为 label_3 的 QLabel 控件的文本内容为“这是一段文字” ui->label_3->setText(\"这是一段文字\"); // 设置 label_3 控件的文本在水平和垂直方向都居中对齐 ui->label_3->setAlignment(Qt::AlignCenter); // 设置 label_3 控件中文本的缩进量为 50,水平和垂直方向都会生效 ui->label_3->setIndent(50); // 设置边距 // 设置名为 label_4 的 QLabel 控件的文本内容为“这是一段文字” ui->label_4->setText(\"这是一段文字\"); // margin -- 设置边距 // 设置 label_4 控件内部文本和边框之间的边距为 20,上下左右四个方向同时有效 ui->label_4->setMargin(20); // 设置 label_4 控件的文本在水平和垂直方向都居中对齐 ui->label_4->setAlignment(Qt::AlignCenter);}// Widget 类的析构函数,用于释放资源Widget::~Widget(){ // 释放 ui 对象所占用的内存 delete ui;}
设置伙伴
此处设置为快捷键+设置为伙伴后就可以通过这个label来选中按钮
3.2.2 LCD Number
QLCDNumer 专门用于显示数字,具有 intValue、value、digitCount、mode、segmentStyle 等核心属性。可通过这些属性设置显示的数字值、数字位数、显示模式(十进制、十六进制等)和显示风格。在实际应用中,常用于实现倒计时功能,如在一个限时抢购页面中,使用 LCD Number 显示剩余时间。
QLCDNumber
显示的数字值(类型为 int
)QLCDNumber
显示的数字值(类型为 double
),与 intValue
联动,如设置 value
为 1.5
,intValue
的值就是 2
QLCDNumber
显示的数字位数QLCDNumber::Dec
:十进制模式,显示常规的十进制数字,只有在此模式下才能显示小数点后的内容QLCDNumber::Hex
:十六进制模式,以十六进制格式显示数字QLCDNumber::Bin
:二进制模式,以二进制格式显示数字QLCDNumber::Oct
:八进制模式,以八进制格式显示数字
QLCDNumber
的显示风格QLCDNumber::Flat
:平面的显示风格,数字呈现在一个平坦的表面上QLCDNumber::Outline
:轮廓显示风格,数字具有清晰的轮廓和阴影效果QLCDNumber::Filled
:填充显示风格,数字被填充颜色并与背景区分开
true
,则显示较小的小数点;设置为 false
则显示正常大小的小数点value
和 intValue
的方法是 display
,而不是 setValue
或者 setIntValue
实现倒计时功能
#include \"widget.h\"#include \"ui_widget.h\"//QTimer 的 timeout 信号在其所属线程发射(默认与父对象线程一致)#include #include Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); //创建一个倒计时 //显示10 ui->lcdNumber->display(10); //用connect来连接实现倒计时 QTimer* t = new QTimer(this); connect(t,&QTimer::timeout,this,&Widget::updatatime); //void start(int msec):启动一个以 msec 毫秒为时间间隔的重复定时器 t->start(1000);}Widget::~Widget(){ delete ui;}void Widget::updatatime(){ qDebug()<lcdNumber->intValue(); //intValue -- QLCDNumber 显⽰的数字值(int) //暂停定时器 if(value stop(); return; }; //设置定时器的倒计时逻辑 ui->lcdNumber->display(--value);}
这里qt是不能使用sleep的
界面假死:如果在主线程(即 GUI 线程)中使用
sleep
函数,会导致整个应用程序的界面无法响应,因为主线程负责处理界面的绘制、用户输入等操作。当sleep
函数使主线程挂起时,界面无法更新,给用户的感觉就是程序卡死了。例如,在一个按钮点击事件处理函数中使用sleep(5)
,在这 5 秒钟内,窗口无法移动、最小化,按钮也无法再次点击等。跨平台问题:标准 C/C++ 库中的
sleep
函数在不同操作系统上的实现和行为可能略有差异(如 Windows 上是Sleep
),这会影响代码的跨平台性。而 Qt 本身提供了更合适的、跨平台的处理等待和延时的方式。
3.2.3 ProgressBar
QProgressBar 用于展示任务进度,核心属性包括 minimum、maximum、value、alignment、textVisible 等。可通过设置这些属性控制进度条的最小值、最大值、当前值、文本对齐方式和数字是否可见等。在实际开发中,进度条的取值通常根据任务实际进度设置,如在文件上传或下载过程中,实时更新进度条以反馈进度情况。
Qt::AlignLeft
:左对齐Qt::AlignRight
:右对齐Qt::AlignCenter
:居中对齐Qt::AlignJustify
:两端对齐true
,则进度条上的数字可见;若为 false
,则不可见true
,进度条从最大值向最小值方向增长;若为 false
,则从最小值向最大值方向增长%p
:表示进度的百分比(0-100)
%v
:表示进度的数值(其范围在进度条的 minimum 到 maximum 之间)
%m
:表示剩余时间(以毫秒为单位)
%t
:表示总时间(以毫秒为单位)
设置进度条按时间增长 + 变红色的进度条
#include \"widget.h\"#include \"ui_widget.h\"#include // Widget 类的构造函数,用于初始化窗口部件Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); // 改变进度条样式 // 使用样式表设置进度条中进度块的背景颜色为红色(#FF0000) // QProgressBar::chunk 表示进度条中表示进度的部分 ui->progressBar->setStyleSheet(\"QProgressBar::chunk{background-color:#FF0000}\"); // 将进度条上显示的数字设置为居中对齐 ui->progressBar->setAlignment(Qt::AlignCenter); // 让 progressBar(进度条) 动起来 // 创建一个定时器对象,并设置父对象为当前窗口部件 QTimer* time = new QTimer(this); // 将定时器的 timeout 信号连接到 handle 槽函数 // timeout 信号可以理解为定时器每次计时结束时发出的信号 connect(time, &QTimer::timeout, this, &Widget::handle); // 启动定时器,设置时间间隔为 100 毫秒 // 即每隔 100 毫秒定时器会发出一次 timeout 信号 time->start(100); }// Widget 类的析构函数,用于释放资源Widget::~Widget(){ // 释放 ui 对象所占用的内存 delete ui;}// 定时器超时的槽函数,用于更新进度条的值void Widget::handle(){ // 获取进度条当前的值 int value = ui->progressBar->value(); // 如果当前值大于 100,说明进度条已完成,停止定时器并返回 if(value > 100){ time->stop(); return; } // 将进度条的值增加 1,并设置回进度条 ui->progressBar->setValue(++value);}
3.2.4 Calendar Widget
QCalendarWidget 用于显示日历,核心属性有 selectDate、minimumDate、maximumDate 等,还包含一些重要信号,如 selectionChanged、activated、currentPageChanged 等。通过这些属性和信号,可获取选中的日期,实现日期选择和相关操作。例如,在一个日程管理软件中,用户可通过日历选择日期,查看和安排当天的日程。
核心属性
重要信号
QDate
类型,保存了新选中的日期QDate
类型,保存了选中的日期获取选中的日期
#include \"widget.h\"#include \"ui_widget.h\"#includeWidget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this);}Widget::~Widget(){ delete ui;}//selectionChanged 发出当前日期信号void Widget::on_calendarWidget_selectionChanged(){ QDate date = ui->calendarWidget->selectedDate(); qDebug()<label->setText(date.toString());}
3.3 输入类控件
3.3.1 Line Edit
QLineEdit 用于实现单行输入功能,核心属性包括 text、inputMask、maxLength 等,还有显示方式(echoMode)、光标位置(cursorPosition)、对齐方式(alignment)等属性。它还包含多个核心信号,如 cursorPositionChanged、editingFinished、returnPressed 等。在实际应用中,可用于录入个人信息,如姓名、密码、电话号码等,并通过设置输入掩码(inputMask)和验证器进行输入格式校验,确保用户输入的数据符合要求。
核心属性
・QLineEdit::Normal :这是默认值,文本框会显示输入的文本。
・QLineEdit::Password :在这种模式下,输入的字符会被隐藏,通常用星号(*)或等号(=)代替。
・QLineEdit::NoEcho :在这种模式下,文本框不会显示任何输入的字符。
核心信号
录入个人信息
#include \"widget.h\"#include \"ui_widget.h\"#include Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); //通过代码实现功能 /*placeholderText 提示信息*/ ui->lineEdit_name->setPlaceholderText(\"请输入姓名\"); /*ClearButtonEnabled 清除输入框的内容*/ ui->lineEdit_name->setClearButtonEnabled(true); ui->lineEdit_passwd->setPlaceholderText(\"请输入密码\"); ui->lineEdit_passwd->setClearButtonEnabled(true); /*EchoMode 显⽰⽅式 QLineEdit::Password 密码显示(通常⽤星号(*)或等号(=)代替) */ ui->lineEdit_passwd->setEchoMode(QLineEdit::Password); ui->lineEdit_phone->setPlaceholderText(\"请输入电话号码\"); ui->lineEdit_phone->setClearButtonEnabled(true); /*InputMask 输入内容格式*/ ui->lineEdit_phone->setInputMask(\"000-0000-0000\"); /*ReadOnly 只读*/ // ui->lineEdit_phone->setReadOnly(true);}Widget::~Widget(){ delete ui;}void Widget::on_pushButton_clicked(){ //如果男被点击就是返回男,否则返回女 QString gender = ui->radioButton_male->isChecked() ? ui->radioButton_male->text() : ui->radioButton_female->text(); //打印信息 qDebug()<<\"姓名:\"<lineEdit_name->text() <<\"密码:\"<lineEdit_passwd->text() <<\"性别:\"<< gender <<\"电话号码\"<lineEdit_phone->text();}
使用正则表达式验证输入框的数据
#include \"widget.h\"#include \"ui_widget.h\"#include// Widget类的构造函数,接收一个QWidget指针作为父组件Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ // 初始化UI界面 ui->setupUi(this); // 代码实现验证字符是否匹配格式(利用正则表达式) // 禁用验证按钮,初始状态下不允许用户点击 ui->pushButton->setEnabled(false); // 设置lineEdit验证器Validator(验证) void setValidator(const QValidator *); // 设置为正则表达式的格式 // QRegExpValidator:这是 Qt 提供的一个验证器类,它可以借助正则表达式来验证输入的内容。 // QRegExp(\"^1\\\\d{10}$\"):这里创建了一个QRegExp对象,该对象代表一个正则表达式。下面详细解释这个正则表达式: // ^:它是正则表达式的开始标记,表示匹配必须从字符串的起始位置开始。 // 1:明确要求字符串的第一个字符必须是数字1。 // \\\\d:这是一个元字符,代表任意一个数字(等价于[0-9])。由于在 C++ 字符串中,反斜杠\\是转义字符,所以要表示一个真正的反斜杠,需要使用两个反斜杠\\\\。 // {10}:这是一个量词,表示前面的元素(也就是\\\\d)必须重复出现恰好 10 次。 // $:它是正则表达式的结束标记,表示匹配必须到字符串的末尾结束。 // 整体这个正则表达式用于验证输入是否为以1开头的11位数字,常用于手机号码的验证。 ui->lineEdit->setValidator(new QRegExpValidator(QRegExp(\"^1\\\\d{10}$\")));}// Widget类的析构函数,用于释放ui对象所占用的内存Widget::~Widget(){ delete ui;}// 验证// 当lineEdit中的文本被编辑时触发此槽函数void Widget::on_lineEdit_textEdited(const QString &arg1){ // arg1 会获取你写入的文字 QString tmp = arg1; int pos = 0; // validate返回值的枚举类型 // enum State { // Invalid, // 无效,输入不满足验证规则 // Intermediate, // 中间状态,输入部分满足规则但还不完整 // Acceptable // 接受,输入完全满足验证规则 // }; // validate 验证函数,用于验证tmp字符串是否符合lineEdit设置的验证规则 if(ui->lineEdit->validator()->validate(tmp, pos) == QValidator::Acceptable) // 如果输入完全满足验证规则,就启用验证按钮,允许用户点击 ui->pushButton->setEnabled(true); else // 如果输入不满足验证规则,就禁用验证按钮,防止用户点击 ui->pushButton->setEnabled(false);}
验证两次输入的密码一致
#include \"widget.h\"#include \"ui_widget.h\"// Widget类的构造函数,接收一个QWidget指针作为父组件Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ // 初始化UI界面 ui->setupUi(this); // 判断密码是否相等 // 设置密码格式,将输入的内容以密码形式显示(通常为星号) // 这里将lineEdit设置为密码输入模式 ui->lineEdit->setEchoMode(QLineEdit::Password); // 这里将lineEdit_2设置为密码输入模式 ui->lineEdit_2->setEchoMode(QLineEdit::Password);}// Widget类的析构函数,用于释放ui对象所占用的内存Widget::~Widget(){ delete ui;}// 当lineEdit中的文本被编辑时触发此槽函数void Widget::on_lineEdit_textEdited(const QString &arg1){ // (void)arg1; 用于避免编译器对未使用参数的警告 (void)arg1; // 获取两个控件的密码 // 从lineEdit中获取用户输入的密码 QString s1 = ui->lineEdit->text(); // 从lineEdit_2中获取用户输入的密码 QString s2 = ui->lineEdit_2->text(); // 判断是否相等 // 如果两个输入框内容都为空 if(s1.isEmpty() && s2.isEmpty()) // 在label上显示提示信息 ui->label->setText(\"内容为空\"); // 如果两个输入框的密码相同 else if(s1 == s2) // 在label上显示密码相同的提示信息 ui->label->setText(\"密码相同\"); // 如果两个输入框的密码不同 else if(s1 != s2) // 在label上显示密码不同并提示重新输入的信息 ui->label->setText(\"密码不同,请重新输入\");}// 当lineEdit_2中的文本被编辑时触发此槽函数void Widget::on_lineEdit_2_textEdited(const QString &arg1){ // (void)arg1; 用于避免编译器对未使用参数的警告 (void)arg1; // 获取两个控件的密码 // 从lineEdit中获取用户输入的密码 QString s1 = ui->lineEdit->text(); // 从lineEdit_2中获取用户输入的密码 QString s2 = ui->lineEdit_2->text(); // 判断是否相等 // 如果两个输入框内容都为空 if(s1.isEmpty() && s2.isEmpty()) // 在label上显示提示信息 ui->label->setText(\"内容为空\"); // 如果两个输入框的密码相同 else if(s1 == s2) // 在label上显示密码相同的提示信息 ui->label->setText(\"密码相同\"); // 如果两个输入框的密码不同 else if(s1 != s2) // 在label上显示密码不同并提示重新输入的信息 ui->label->setText(\"密码不同,请重新输入\");}
切换显示密码
#include \"widget.h\"#include \"ui_widget.h\"// Widget类的构造函数,接收一个QWidget指针作为父组件Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ // 初始化UI界面 ui->setupUi(this);}// Widget类的析构函数,用于释放ui对象所占用的内存Widget::~Widget(){ delete ui;}// 当复选框被点击时,会触发此槽函数,checked参数表示复选框当前的选中状态void Widget::on_checkBox_clicked(bool checked){ // 判断复选框是否被按下 // 如果复选框被选中 if(checked) { // 将lineEdit的显示模式设置为密码模式,输入的内容会以密码形式显示(通常是星号) ui->lineEdit->setEchoMode(QLineEdit::Password); } // 如果复选框未被选中 else { // 将lineEdit的显示模式设置为正常模式,输入的内容会正常显示 ui->lineEdit->setEchoMode(QLineEdit::Normal); }}
3.3.2 Text Edit
QTextEdit 是多行输入框,也是富文本和 markdown 编辑器,具备 markdown、html、placeHolderText 等核心属性,以及 textChanged、selectionChanged、cursorPositionChanged 等核心信号。可用于获取多行输入框的内容,实现文本编辑和实时预览等功能。例如,在一个简单的文本编辑器中,用户可输入多行文本,进行格式编辑,程序实时显示编辑效果。
核心属性的表格:
以下是核心信号的表格:
获取多行输入框的内容
验证输入框的各种信号
#include \"widget.h\"#include \"ui_widget.h\"#includeWidget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this);}Widget::~Widget(){ delete ui;}//测试TexteEdit所有的信号void Widget::on_textEdit_textChanged(){ qDebug()<<\"textChanged\"<textEdit->toPlainText();}//鼠标选中范围void Widget::on_textEdit_selectionChanged(){ //接收返回的鼠标位置 const QTextCursor& cursor = ui->textEdit->textCursor(); //打印鼠标选中范围selecedText qDebug()<<\"selectionChanged\"<textEdit->textCursor(); qDebug()<<\"cursorPositionChanged\"<<cursor.position();}//是否可以复制void Widget::on_textEdit_copyAvailable(bool b){ qDebug()<<\"copyAvailable\"<<b;}//是否可以逆撤回void Widget::on_textEdit_redoAvailable(bool b){ qDebug()<<\"redoAvailable\"<<b;}//是否可以撤回void Widget::on_textEdit_undoAvailable(bool b){ qDebug()<<\"undoAvailable\"<<b;}
3.3.3 Combo Box
QComboBox 表示下拉框,核心属性有 currentText、currentIndex、editable 等,核心方法包括 addItem、currentIndex、currentText 等,核心信号有 activated、currentIndexChanged 等。在实际应用中,可用于模拟点餐场景,从文件中加载选项等。比如在一个在线点餐系统中,用户通过下拉框选择菜品和饮料。
核心属性表格:
核心方法表格:
核心信号表格:
使用下拉框模拟买东西
从文件中加载下拉框的选项
std::ifstream
:这是 C++ 标准库头文件中定义的一个类,用于实现从文件中读取数据的功能,即文件输入流。通过创建
std::ifstream
类的对象,并在构造函数中传入要打开的文件路径,就可以建立与该文件的连接,以便后续读取文件内容。is_open()
:这是std::ifstream
类的成员函数。其作用是检查通过std::ifstream
对象尝试打开的文件是否成功打开。如果文件成功打开,该函数返回true
;如果文件打开失败(例如文件不存在、权限不足等原因),则返回false
。通常在打开文件后会调用这个函数来判断文件是否可用,以避免在文件未成功打开的情况下进行无效的读取操作。close()
:这也是std::ifstream
类的成员函数。当对文件的读取操作完成后,调用close()
函数可以关闭之前通过std::ifstream
对象与文件建立的连接,释放与该文件相关的系统资源(如文件句柄等)。关闭文件是良好的编程习惯,确保资源得到合理管理,防止出现资源泄漏等问题。
#include \"widget.h\"#include \"ui_widget.h\"#include #include #include #include // Widget 类的构造函数,parent 为父窗口指针,默认为 nullptrWidget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ // 设置用户界面,将设计好的 UI 布局应用到当前窗口 ui->setupUi(this); // 通过读取文件,把文件内容加入下拉列表 // 以输入模式打开指定路径的文件 std::ifstream file(\"E:\\\\QT_study\\\\c++\\\\file_QComboBox\\\\read.txt\"); // 检查文件是否成功打开 if (!file.is_open()) { // 如果文件打开失败,使用 qDebug 输出错误信息 qDebug() <comboBox->addItem(QString::fromStdString(line)); } // 关闭文件流,释放系统资源 file.close();}// Widget 类的析构函数,用于释放 ui 对象占用的内存Widget::~Widget(){ delete ui;}// 当下拉列表中的选项被激活(用户选择了一个选项)时,触发此槽函数// 此函数用于打印当前选中的文字void Widget::on_comboBox_activated(const QString &arg1){ // 使用 qDebug 输出当前选中的文字 qDebug() << arg1;}// 当下拉列表中的选项被激活(用户选择了一个选项)时,触发此槽函数// 此函数用于打印当前选中选项的下标void Widget::on_comboBox_activated(int index){ // 使用 qDebug 输出当前选中选项的下标 qDebug() << index;}
3.3.4 Spin Box
QSpinBox 和 QDoubleSpinBox 用于实现微调功能,可输入整数或浮点数。以 QSpinBox 为例,其关键属性有 value、singleStep、displayInteger 等,核心信号有 textChanged、valueChanged 等。在实际应用中,可用于调整购物车中商品的份数,如在电商购物车界面中,用户可通过微调框增加或减少商品数量。
核心属性表格:
核心信号表格:
调整麦当劳购物车中的份数
#include \"widget.h\"#include \"ui_widget.h\"#include // Widget 类的构造函数,parent 为父窗口指针,默认值为 nullptrWidget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ // 调用 setupUi 函数来设置用户界面,将设计好的 UI 布局应用到当前窗口 ui->setupUi(this); // 设置下拉框数据 // 为第一个下拉框 comboBox 添加选项 \"big汉堡\" 和 \"small汉堡\" ui->comboBox->addItem(\"big汉堡\"); ui->comboBox->addItem(\"small汉堡\"); // 为第二个下拉框 comboBox_2 添加选项 \"可乐\" 和 \"雷碧\" ui->comboBox_2->addItem(\"可乐\"); ui->comboBox_2->addItem(\"雷碧\"); // 为第三个下拉框 comboBox_3 添加选项 \"韩国薯条\" 和 \"漂亮国薯条\" ui->comboBox_3->addItem(\"韩国薯条\"); ui->comboBox_3->addItem(\"漂亮国薯条\"); // 设置数据范围 // 设置第一个自旋框 spinBox 的取值范围为 1 到 10 ui->spinBox->setRange(1, 10); // 设置第二个自旋框 spinBox_2 的取值范围为 1 到 10 ui->spinBox_2->setRange(1, 10); // 设置第三个自旋框 spinBox_3 的取值范围为 1 到 10 ui->spinBox_3->setRange(1, 10);}// Widget 类的析构函数,用于释放 ui 对象所占用的内存Widget::~Widget(){ delete ui;}// 当名为 pushButton 的按钮被点击时,会触发该槽函数void Widget::on_pushButton_clicked(){ // 使用 qDebug 输出当前各个下拉框选中的文本以及对应的自旋框中的文本 // 输出格式为:下拉框选中的文本 : 自旋框中的文本 qDebug() <comboBox->currentText() << \":\" <spinBox->text() <comboBox_2->currentText() << \":\" <spinBox_2->text() <comboBox_3->currentText() << \":\" <spinBox_3->text();}
3.3.5 Date Edit & Time Edit
QDateEdit、QTimeEdit 和 QDateTimeEdit 分别用于日期、时间和时间日期的微调。以 QDateTimeEdit 为例,核心属性有 dateTime、date、time 等,核心信号有 dateChanged、timeChanged、dateTimeChanged 等。在实际应用中,可用于实现日期计算器等功能,如在一个恋爱纪念日计算程序中,通过选择两个日期,计算出恋爱持续的天数和小时数。
协调世界时(UTC)
协调世界时(UTC)是一个基于原子钟的标准时间,其具有高度的准确性和稳定性,不受地球自转周期的影响。它与格林威治时间(GMT)非常接近,由科学家通过精密的设备进行测量和维护。在计算机内部,所使用的时间就是基于 UTC 时间。
本地时间(LocalTime)
本地时间是基于不同的时区,对 UTC 时间做出相应调整后得到的时间。以北京时间为例,北京位于 “东八区”,这意味着北京时间需要在 UTC 时间的基础上加上 8 个小时的时差。也就是说,当 UTC 时间为某一时刻时,北京时间是在这个时刻的基础上再过 8 个小时的时间点。
核心属性表格:
核心信号表格:
实现日期计算器
#include \"widget.h\"#include \"ui_widget.h\"#include // Widget 类的构造函数,parent 为父窗口指针,默认值为 nullptrWidget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ // 调用 setupUi 函数来设置用户界面,将设计好的 UI 布局应用到当前窗口 ui->setupUi(this);}// Widget 类的析构函数,用于释放 ui 对象所占用的内存Widget::~Widget(){ delete ui;}// 通过按钮来计算的槽函数,当 pushButton 按钮被点击时触发void Widget::on_pushButton_clicked(){ // 获取控件时间 // 从 dateTimeEdit 控件中获取日期时间值,并赋值给 old_time QDateTime old_time = ui->dateTimeEdit->dateTime(); // 从 dateTimeEdit_2 控件中获取日期时间值,并赋值给 new_time QDateTime new_time = ui->dateTimeEdit_2->dateTime(); // 计算天数 // daysTo 返回从这个日期时间到另一个日期时间的天数。 // 天数的计算方法是统计从这个日期时间到另一个日期时间之间经历午夜(凌晨零点)的次数。这就意味着 // 从当天 23:55 到次日 0:05 这样 10 分钟的时间差算作一天。 // 这里注释掉了原来有问题的代码,因为 daysTo 函数计算的是日期之间的天数差,不是时间差的天数 // int day = old_time.daysTo(new_time);//bug // qDebug() <label->setText(con);}
3.3.6 Dial
QDial 表示旋钮,核心属性有 value、minimum、maximum 等,核心信号有 valueChanged、rangeChanged 等。在实际应用中,可用于调整窗口透明度等功能,如在一个图像编辑软件中,通过旋转旋钮调整图片的透明度。
核心属性表格:
核心信号表格:
调整窗口透明度
#include \"widget.h\"#include \"ui_widget.h\"#include // Widget类的构造函数,parent为指向父窗口的指针,默认值为nullptrWidget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ // 调用setupUi函数,将UI设计器中创建的界面布局应用到当前窗口 ui->setupUi(this); // 设置拨号盘(dial)的初始值为100 ui->dial->setValue(100); // 设置拨号盘(dial)的最小值为0 ui->dial->setMinimum(0); // 设置拨号盘(dial)的最大值为100 ui->dial->setMaximum(100); // 设置拨号盘(dial)允许循环转动,即当数值超过最大值时回到最小值 ui->dial->setWrapping(true); // 使拨号盘(dial)显示刻度线 ui->dial->setNotchesVisible(true); // 设置拨号盘(dial)刻度线之间的相对位置,值越小刻度线越密集,这里设置为0.1 ui->dial->setNotchTarget(0.1);}// Widget类的析构函数,用于释放ui对象所占用的内存Widget::~Widget(){ delete ui;}// 当拨号盘(dial)的值发生变化时,会触发这个槽函数// value参数表示拨号盘当前的数值void Widget::on_dial_valueChanged(int value){ // 使用qDebug输出当前拨号盘的数值 qDebug() <label->setText(context); // 根据当前拨号盘的数值value来调节窗口的透明度 // 将value转换为double类型并除以100,得到0到1之间的透明度值 setWindowOpacity((double)value / 100);}
3.3.7 Slider
QSlider 表示滑动条,与 QDial 用法相似,继承自 QAbstractSlider。核心属性有 value、minimum、maximum 等,核心信号有 valueChanged、rangeChanged 等。在实际应用中,可用于调整窗口大小,通过自定义快捷键调整滑动条位置等。比如在一个视频播放软件中,用户可通过滑动条调整视频音量或播放进度。
核心属性表格:
pageUp
/pageDown
键时数值改变的步长true
,一般无需修改核心信号表格:
int
表示当前的数值调整窗口大小
#include \"widget.h\"#include \"ui_widget.h\"// Widget 类的构造函数,parent 为指向父窗口的指针,默认值为 nullptrWidget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ // 调用 setupUi 函数,将 UI 设计器中创建的界面布局应用到当前窗口 ui->setupUi(this); // 设置垂直滑动条(verticalSlider)的属性 // 设置垂直滑动条的最小值为 500 ui->verticalSlider->setMinimum(500); // 设置垂直滑动条的最大值为 2000 ui->verticalSlider->setMaximum(2000); // 设置垂直滑动条的初始值为 600 ui->verticalSlider->setValue(600); // 设置水平滑动条(horizontalSlider)的属性 // 设置水平滑动条的最小值为 500 ui->horizontalSlider->setMinimum(500); // 设置水平滑动条的最大值为 2000 ui->horizontalSlider->setMaximum(2000); // 设置水平滑动条的初始值为 800 ui->horizontalSlider->setValue(800);}// Widget 类的析构函数,用于释放 ui 对象所占用的内存Widget::~Widget(){ delete ui;}// 当水平滑动条(horizontalSlider)的值发生变化时,会触发这个槽函数// value 参数表示水平滑动条当前的数值void Widget::on_horizontalSlider_valueChanged(int value){ // 获取当前窗口的几何信息,包括位置和大小 QRect rect = geometry(); // 根据水平滑动条的当前值,重新设置窗口的几何信息 // 保持窗口的 x 坐标和 y 坐标不变,将窗口的宽度设置为水平滑动条的当前值,高度保持不变 setGeometry(rect.x(), rect.y(), value, rect.height());}// 当垂直滑动条(verticalSlider)的值发生变化时,会触发这个槽函数// value 参数表示垂直滑动条当前的数值void Widget::on_verticalSlider_valueChanged(int value){ // 获取当前窗口的几何信息,包括位置和大小 QRect rect = geometry(); // 根据垂直滑动条的当前值,重新设置窗口的几何信息 // 保持窗口的 x 坐标和 y 坐标不变,将窗口的高度设置为垂直滑动条的当前值,宽度保持不变 setGeometry(rect.x(), rect.y(), rect.width(), value);}
通过自定义快捷键调整滑动条位置
#include \"widget.h\"#include \"ui_widget.h\"#include// Widget类的构造函数,parent为父窗口指针,默认值为nullptrWidget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ // 调用setupUi函数,将UI设计器中设计好的界面布局应用到当前窗口 ui->setupUi(this); // 设置水平滑动条的最小值为1 ui->horizontalSlider->setMinimum(1); // 设置水平滑动条的最大值为100 ui->horizontalSlider->setMaximum(100); // 设置水平滑动条每次按方向键时改变的步长为3 ui->horizontalSlider->setSingleStep(3); // 通过使用快捷键来实现移动 // 创建两个QShortcut对象,用于处理快捷键操作,this表示该快捷键对象的父对象为当前Widget QShortcut *cut1 = new QShortcut(this); QShortcut *cut2 = new QShortcut(this); // 设置快捷键 // 将cut1的快捷键设置为按下“=”键 cut1->setKey(QKeySequence(\"=\")); // 将cut2的快捷键设置为按下“-”键 cut2->setKey(QKeySequence(\"-\")); // 槽函数连接 // 当按下“=”快捷键时,触发addValue槽函数 connect(cut1, &QShortcut::activated, this, &Widget::addValue); // 当按下“-”快捷键时,触发subValue槽函数 connect(cut2, &QShortcut::activated, this, &Widget::subValue);}// Widget类的析构函数,用于释放ui对象占用的内存Widget::~Widget(){ delete ui;}// 当水平滑动条的值发生改变时,此槽函数会被调用void Widget::on_horizontalSlider_valueChanged(int value){ // 设置label标签的文本,显示当前水平滑动条的值 ui->label->setText(QString(\"当前显示:\") + QString::number(value));}// 当按下“=”快捷键时,执行此槽函数,增加水平滑动条的值void Widget::addValue(){ // 获取当前水平滑动条的值 int value = ui->horizontalSlider->value(); // 将水平滑动条的值加1并重新设置 ui->horizontalSlider->setValue(value + 1);}// 当按下“-”快捷键时,执行此槽函数,减少水平滑动条的值void Widget::subValue(){ // 获取当前水平滑动条的值 int value = ui->horizontalSlider->value(); // 将水平滑动条的值减1并重新设置 ui->horizontalSlider->setValue(value - 1);}
3.4 多元素控件
3.4.1 List Widget
QListWidget 用于显示纵向列表,核心属性包括 currentRow、count、sortingEnabled 等,核心方法有 addItem、currentItem、setCurrentItem 等,核心信号有 currentItemChanged、currentRowChanged 等。在实际应用中,可用于展示多个选项,实现元素的添加、删除和选中操作。例如,在一个待办事项列表中,用户可添加新的事项,选中并删除已完成的事项。
QListWidget 核心属性
QListWidget 核心方法
addItem(QListWidgetItem *item)
QListWidgetItem
对象添加QListWidgetItem*
类型,表示当前选中的元素insertItem(QListWidgetItem *item, int row)
QListWidgetItem
对象QListWidgetItem*
类型,表示指定行的元素QListWidgetItem*
对象QListWidget 核心信号
QListWidgetItem 核心方法
#include \"widget.h\"#include \"ui_widget.h\"#include // Widget类的构造函数,parent为父窗口指针,默认为nullptrWidget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ // 设置用户界面 ui->setupUi(this); // 以下两行代码被注释掉了,它们的作用是直接向列表部件中添加字符串元素 // 这两种方式会自动创建QListWidgetItem对象并添加到列表中// ui->listWidget->addItem(\"c++\");// ui->listWidget->addItem(\"java\"); // 以下两行代码同样被注释掉了,它们通过手动创建QListWidgetItem对象并添加到列表中 // 与上面的方式相比,这种方式可以更灵活地设置元素的属性,如字体、图标等// ui->listWidget->addItem(new QListWidgetItem(\"c++\"));// ui->listWidget->addItem(new QListWidgetItem(\"java\"));}// Widget类的析构函数,用于释放ui对象所占用的内存Widget::~Widget(){ delete ui;}// 当“添加”按钮被点击时,此槽函数会被调用void Widget::on_pushButton_add_clicked(){ // 获取输入框(lineEdit)中的文本内容 QString text = ui->lineEdit->text(); // 将获取到的文本添加到列表部件(listWidget)中 ui->listWidget->addItem(text);}// 当“删除”按钮被点击时,此槽函数会被调用void Widget::on_pushButton_delete_clicked(){ // 获取列表部件中当前选中项的行号 int Row = ui->listWidget->currentRow(); // 从列表部件中移除指定行号的项,并返回被移除的项的指针 ui->listWidget->takeItem(Row);}// 当列表部件中选中的项发生变化时,此槽函数会被调用// current为当前选中的项,previous为上一个选中的项void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous){ // 检查当前选中项和上一个选中项是否都不为空 if(current != nullptr && previous != nullptr) { // 打印当前选中项的文本内容 qDebug()<<\"当前选中:\"<text(); // 打印上一个选中项的文本内容 qDebug()<<\"上一个:\"<text(); }}
3.4.2 Table Widget
QTableWidget 用于显示表格,包含若干行和列,每个单元格是一个 QTableWidgetItem 对象。它具有丰富的核心方法,如 item、setItem、currentItem 等,以及多个核心信号,如 cellClicked、cellDoubleClicked 等。在实际应用中,可用于展示和编辑表格数据,如在一个学生成绩管理系统中,以表格形式展示学生的学号、姓名、成绩等信息,并支持数据的添加、删除和修改。
QTableWidget 核心方法
QTableWidgetItem*
QTableWidgetItem*
item
所在的行号item
所在的列号row
行处插入新行column
列处插入新列row
行column
列QTableWidget 核心信号
QTableWidgetItem 核心方法
使用 QTableWidget 简单理解就是一个二维表格
#include \"widget.h\"#include \"ui_widget.h\"#include // Widget 类的构造函数,接收一个父窗口指针作为参数Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); // 通过代码的方式添加三行到表格中 // insertRow 函数用于在指定行索引处插入新行,这里依次在第 0、1、2 行插入 ui->tableWidget->insertRow(0); ui->tableWidget->insertRow(1); ui->tableWidget->insertRow(2); // 通过代码的方式添加三列到表格中 // insertColumn 函数用于在指定列索引处插入新列,这里依次在第 0、1、2 列插入 ui->tableWidget->insertColumn(0); ui->tableWidget->insertColumn(1); ui->tableWidget->insertColumn(2); // 设置表格的水平表头,即列标题 // setHorizontalHeaderItem 函数用于设置指定列的表头项,这里分别设置第 0、1、2 列的表头 ui->tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem(\"姓名\")); ui->tableWidget->setHorizontalHeaderItem(1,new QTableWidgetItem(\"学号\")); ui->tableWidget->setHorizontalHeaderItem(2,new QTableWidgetItem(\"年龄\")); // 向表格中添加内容 // setItem 函数用于设置表格中指定行和列的单元格内容 ui->tableWidget->setItem(0,0,new QTableWidgetItem(\"张三\")); ui->tableWidget->setItem(0,1,new QTableWidgetItem(\"001\")); ui->tableWidget->setItem(0,2,new QTableWidgetItem(\"2023/2/2\")); ui->tableWidget->setItem(1,0,new QTableWidgetItem(\"里斯三\")); ui->tableWidget->setItem(1,1,new QTableWidgetItem(\"001\")); ui->tableWidget->setItem(1,2,new QTableWidgetItem(\"2023/2/2\")); ui->tableWidget->setItem(2,0,new QTableWidgetItem(\"八八三\")); ui->tableWidget->setItem(2,1,new QTableWidgetItem(\"001\")); ui->tableWidget->setItem(2,2,new QTableWidgetItem(\"2023/2/2\")); // 为添加列的按钮设置提示信息 // setToolTip 函数用于设置控件的提示信息,当鼠标悬停在按钮上时会显示该信息 ui->pushButton_addcol->setToolTip(\"请先写表头名\");}// Widget 类的析构函数,用于释放 ui 对象所占用的内存Widget::~Widget(){ delete ui;}// 当添加行按钮被点击时触发的槽函数void Widget::on_pushButton_addrow_clicked(){ // 获取当前表格的行数 int row = ui->tableWidget->rowCount(); // 在表格的末尾插入一行新行 ui->tableWidget->insertRow(row);}// 当删除行按钮被点击时触发的槽函数void Widget::on_pushButton_deleterow_clicked(){ // 获取当前选中的行的索引 int currow = ui->tableWidget->currentRow(); // 删除选中的行 ui->tableWidget->removeRow(currow);}// 当添加列按钮被点击时触发的槽函数void Widget::on_pushButton_addcol_clicked(){ // 获取当前表格的列数 int col = ui->tableWidget->columnCount(); // 输出当前列数到调试窗口 qDebug()< tableWidget->insertColumn(col); // 获取输入框中的文本,作为新列的表头 QString text = ui->lineEdit->text(); // 设置新列的表头 ui->tableWidget->setHorizontalHeaderItem(col,new QTableWidgetItem(text));}// 当删除列按钮被点击时触发的槽函数void Widget::on_pushButton_deletecol_clicked(){ // 获取当前选中的列的索引 int curcol = ui->tableWidget->currentColumn(); // 删除选中的列 ui->tableWidget->removeColumn(curcol);}
3.4.3 Tree Widget
QTreeWidget 用于显示树形结构,每个元素是一个 QTreeWidgetItem,可包含多个文本和图标。核心方法有 addTopLevelItem、topLevelItem、currentItem 等,核心信号有 currentItemChanged、itemClicked 等。在实际应用中,可用于展示层级关系数据,如在一个文件资源管理器中,以树形结构展示文件夹和文件的层级关系。
QTreeWidget 核心方法
QTreeWidgetItem*
QTreeWidgetItem*
TreeWidget
的 header
名称QTreeWidget 核心信号
QTreeWidgetItem 核心属性
QTreeWidgetItem 核心方法
QTreeWidgetItem*
使用 QTreeWidget
但是还是用代码的方式
#include \"widget.h\"#include \"ui_widget.h\"// Widget类的构造函数,接收一个QWidget类型的指针作为参数,用于指定父窗口Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); // 设置树形控件的表头标签为\"动物\" ui->treeWidget->setHeaderLabel(\"动物\"); // 注释掉的代码:设置树形控件的列数为2,这里被注释掉了,实际不会生效 // ui->treeWidget->setColumnCount(2); // 创建一个QTreeWidgetItem对象item1,用于表示\"狗\"节点 QTreeWidgetItem* item1 = new QTreeWidgetItem(); // 设置item1的第一列文本为\"狗\" item1->setText(0, \"狗\"); // 将item1添加为树形控件的顶级项(即根节点) ui->treeWidget->addTopLevelItem(item1); // 创建一个QTreeWidgetItem对象item2,用于表示\"猫\"节点 QTreeWidgetItem* item2 = new QTreeWidgetItem(); // 设置item2的第一列文本为\"猫\" item2->setText(0, \"猫\"); // 将item2添加为树形控件的顶级项(即根节点) ui->treeWidget->addTopLevelItem(item2); // 创建一个QTreeWidgetItem对象item3,用于表示\"鸟\"节点 QTreeWidgetItem* item3 = new QTreeWidgetItem(); // 设置item3的第一列文本为\"鸟\" item3->setText(0, \"鸟\"); // 将item3添加为树形控件的顶级项(即根节点) ui->treeWidget->addTopLevelItem(item3); // 注释掉的代码:创建\"狗\"节点的子节点,这里被注释掉了,实际不会生效 // QTreeWidgetItem* item4 = new QTreeWidgetItem(); // item4->setText(1, \"金毛\"); // item1->addChild(item4); // QTreeWidgetItem* item5 = new QTreeWidgetItem(); // item5->setText(1, \"aaaa\"); // item1->addChild(item5);}// Widget类的析构函数,用于释放ui对象所占用的内存Widget::~Widget(){ delete ui;}// 当\"add\"按钮被点击时触发的槽函数void Widget::on_pushButton_clicked(){ // 获取输入框(lineEdit)中的内容,并将其存储为一个const QString引用 const QString& text = ui->lineEdit->text(); // 如果输入框内容为空,则直接返回,不执行后续操作 if (text.isEmpty()) { return; } // 创建一个新的QTreeWidgetItem对象Item_tmp,用于表示新的节点 QTreeWidgetItem* Item_tmp = new QTreeWidgetItem(); // 设置Item_tmp的第一列文本为输入框中的内容 Item_tmp->setText(0, text); // 将Item_tmp添加为树形控件的顶级项(即根节点) ui->treeWidget->addTopLevelItem(Item_tmp);}// 当\"hold\"按钮被点击时触发的槽函数void Widget::on_pushButton_2_clicked(){ // 获取输入框(lineEdit)中的内容,并将其存储为一个const QString引用 const QString& text = ui->lineEdit->text(); // 如果输入框内容为空,则直接返回,不执行后续操作 if (text.isEmpty()) { return; } // 获取当前在树形控件中选中的项 QTreeWidgetItem* pos = ui->treeWidget->currentItem(); // 如果没有选中任何项(pos为nullptr),则直接返回,不执行后续操作 if (pos == nullptr) { return; } // 创建一个新的QTreeWidgetItem对象Item_tmp,用于表示新的子节点 QTreeWidgetItem *Item_tmp = new QTreeWidgetItem(); // 设置Item_tmp的第一列文本为输入框中的内容 Item_tmp->setText(0, text); // 将Item_tmp添加为当前选中项(pos)的子节点 pos->addChild(Item_tmp);}// 当\"remove\"按钮被点击时触发的槽函数void Widget::on_pushButton_3_clicked(){ // 获取当前在树形控件中选中的项 QTreeWidgetItem *repos = ui->treeWidget->currentItem(); // 如果没有选中任何项(repos为nullptr),则直接返回,不执行后续操作 if (repos == nullptr) { return; } // 获取当前选中项(repos)的父节点 QTreeWidgetItem* parent = repos->parent(); // 如果父节点为nullptr,说明当前选中项是顶级项(根节点) if (parent == nullptr) { // 查询当前选中项在顶级项中的索引 int value = ui->treeWidget->indexOfTopLevelItem(repos); // 从树形控件中移除指定索引的顶级项 ui->treeWidget->takeTopLevelItem(value); } else { // 如果当前选中项有父节点,则从父节点中移除当前选中项 parent->removeChild(repos); }}
3.5 容器类控件
3.5.1 Group Box
QGroupBox 用于实现带有标题的分组框,可将其他控件分组,使界面更美观。核心属性有 title、alignment、flat 等。在实际应用中,可用于整理界面元素,如在一个设置界面中,将相关的设置选项放在一个分组框内,增强界面的可读性。
title
alignment
flat
checkable
true
,则在 title
前方会多出一个可勾选的部分checked
checkable
为 true
)给麦当劳案例加上分组框这个案例我前面演示过,其实就是将不同控件分组这样就不会相互干扰
通过这个控件把来禁止按钮是否能被按下,这就可以体现出容器类控件的作用
3.5.2 Tab Widget
QTabWidget 用于实现带有标签页的控件,可通过标签页切换不同的内容。核心属性有 tabPosition、currentIndex、currentTabText 等,核心信号有 currentChanged、tabBarClicked 等。在实际应用中,可用于管理多组控件,如在一个多功能软件中,通过标签页切换不同的功能模块界面。
属性及其说明
tabPosition
•
North
:上方•
South
:下方•
West
:左侧•
East
:右侧currentIndex
currentTabText
currentTabName
currentTabIcon
currentTabToolTip
tabsCloseable
movable
核心信号及其说明
currentChanged(int)
tabBarClicked(int)
tabBarDoubleClicked(int)
tabCloseRequest(int)
使用标签页管理多组控件
#include \"widget.h\"#include \"ui_widget.h\"#include // Widget类的构造函数,接收一个QWidget类型的指针作为参数,用于指定父窗口Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); // 初始化用户界面,将.ui文件中设计的界面加载到当前Widget中}// Widget类的析构函数,用于释放ui对象所占用的内存Widget::~Widget(){ delete ui;}// 当tabWidget的标签页关闭请求信号(tabCloseRequested)触发时执行的槽函数// 参数index表示要关闭的标签页的索引void Widget::on_tabWidget_tabCloseRequested(int index){ // 从tabWidget中移除指定索引的标签页 ui->tabWidget->removeTab(index);}// 当pushButton按钮被点击时执行的槽函数void Widget::on_pushButton_clicked(){ // 创建一个新的QWidget对象,每个标签页本质上就是一个QWidget QWidget* mm = new QWidget(); // 获取当前tabWidget中标签页的数量 int count = ui->tabWidget->count(); // 向tabWidget中添加一个新的标签页,标签页的内容为新建的QWidget对象mm // 标签页的标题为\"Tab \"加上当前标签页数量加1的字符串表示 ui->tabWidget->addTab(mm, QString(\"Tab \") + QString::number(count + 1)); // 创建一个QLabel对象,作为新标签页中的显示内容,父对象为新建的QWidget对象mm QLabel *label = new QLabel(mm); // 调整标签的大小为200x200像素 label->resize(200, 200); // 设置标签的文本内容,为\"这是一个标签页\"加上当前标签页数量加1的字符串表示 label->setText(QString(\"这是一个标签页\") + QString::number(count + 1)); // 将当前选中的标签页设置为新添加的标签页,索引为当前标签页数量 ui->tabWidget->setCurrentIndex(count);}// 当pushButton_2按钮被点击时执行的槽函数void Widget::on_pushButton_2_clicked(){ // 获取当前选中的标签页的索引 int index = ui->tabWidget->currentIndex(); // 从tabWidget中移除当前选中的标签页 ui->tabWidget->removeTab(index);}
3.6 布局管理器
3.6.1 垂直布局(QVBoxLayout)
QVBoxLayout 用于实现垂直布局,核心属性包括 layoutLeftMargin(左侧边距)、layoutRightMargin(右侧边距)、layoutTopMargin(上方边距)、layoutBottomMargin(下方边距)、layoutSpacing(相邻元素之间的间距) 。Layout 只是用于界面布局,并没有提供信号。
layoutLeftMargin
layoutRightMargin
layoutTopMargin
layoutBottomMargin
layoutSpacing
3.6.2 水平布局(QHBoxLayout)
QHBoxLayout 用于实现水平布局,H 是 horizontal 的缩写。其核心属性和 QVBoxLayout 属性一致,包括 layoutLeftMargin(左侧边距)、layoutRightMargin(右侧边距)、layoutTopMargin(上方边距)、layoutBottomMargin(下方边距)、layoutSpacing(相邻元素之间的间距) 。
#include \"widget.h\"#include \"ui_widget.h\"#include // 引入垂直布局类的头文件,用于创建垂直方向的布局管理器#include // 引入水平布局类的头文件,用于创建水平方向的布局管理器#include // 引入按钮类的头文件,用于创建按钮控件// Widget类的构造函数,接收一个QWidget类型的指针作为参数,用于指定父窗口Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); // 初始化用户界面,将.ui文件中设计的界面加载到当前Widget中 // 创建一个垂直布局管理器对象vlay,并指定当前Widget为其父对象 QVBoxLayout *vlay = new QVBoxLayout(this); // 创建三个按钮控件 QPushButton *button1 = new QPushButton(\"按钮一\"); QPushButton *button2 = new QPushButton(\"按钮二\"); QPushButton *button3 = new QPushButton(\"按钮三\"); // 将三个按钮依次添加到垂直布局管理器vlay中 vlay->addWidget(button1); vlay->addWidget(button2); vlay->addWidget(button3); // 创建一个水平布局管理器对象hlay QHBoxLayout *hlay = new QHBoxLayout(); // 创建两个按钮控件 QPushButton *button4 = new QPushButton(\"按钮四\"); QPushButton *button5 = new QPushButton(\"按钮五\"); // 将两个按钮依次添加到水平布局管理器hlay中 hlay->addWidget(button4); hlay->addWidget(button5); // 将水平布局管理器hlay添加到垂直布局管理器vlay中,实现布局的嵌套 vlay->addLayout(hlay);}// Widget类的析构函数,用于释放ui对象所占用的内存Widget::~Widget(){ delete ui;}
3.6.3 网格布局(QGridLayout)
Qt 中还提供了 QGridLayout 用来实现网格布局的效果,可以达到 M * N 的这种网格的效果。
核心属性整体和 QVBoxLayout 以及 QHBoxLayout 相似,但是设置 spacing 的时候是按照垂直水平两个方向来设置的,包括 layoutLeftMargin(左侧边距)、layoutRightMargin(右侧边距)、layoutTopMargin(上方边距)、layoutBottomMargin(下方边距)、layoutHorizontalSpacing(相邻元素之间水平方向的间距)、layoutVerticalSpacing(相邻元素之间垂直方向的间距)、layoutRowStretch(行方向的拉伸系数)、layoutColumnStretch(列方向的拉伸系数) 。
layoutLeftMargin
layoutRightMargin
layoutTopMargin
layoutBottomMargin
layoutHorizontalSpacing
layoutVerticalSpacing
layoutRowStretch
layoutColumnStretch
使用 QGridLayout 管理元素
#include \"widget.h\"#include \"ui_widget.h\"#include // 引入 QPushButton 类,用于创建按钮控件#include // 引入 QGridLayout 类,用于创建网格布局管理器// Widget 类的构造函数,接收一个 QWidget 类型的指针作为参数,用于指定父窗口Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); // 初始化用户界面,将.ui 文件中设计的界面加载到当前 Widget 中 // 创建四个按钮对象,分别设置按钮的文本为 \"按钮1\" QPushButton* button1 = new QPushButton(\"按钮1\"); QPushButton* button2 = new QPushButton(\"按钮1\"); QPushButton* button3 = new QPushButton(\"按钮1\"); QPushButton* button4 = new QPushButton(\"按钮1\"); // 创建一个网格布局管理器对象 layout,并指定当前 Widget 为其父对象 QGridLayout* layout = new QGridLayout(this); // 以下代码被注释掉了,其作用是将按钮依次添加到布局中,按默认顺序排列 // layout->addWidget(button1); // layout->addWidget(button2); // layout->addWidget(button3); // layout->addWidget(button4); // 以下代码被注释掉了,其作用是将按钮添加到网格布局的指定位置 // 第一个参数是要添加的控件,第二个参数是行索引,第三个参数是列索引 // layout->addWidget(button1,0,0); // layout->addWidget(button2,0,1); // layout->addWidget(button3,1,0); // layout->addWidget(button4,1,1); // 将按钮 1 添加到网格布局的第 1 行、第 0 列 layout->addWidget(button1,1,0); // 将按钮 2 添加到网格布局的第 2 行、第 0 列 layout->addWidget(button2,2,0); // 将按钮 3 添加到网格布局的第 3 行、第 0 列 layout->addWidget(button3,3,0); // 将按钮 4 添加到网格布局的第 12 行、第 0 列 // 即使行数跨度较大,也不会使按钮间隔过大,因为网格布局会自动处理空间分配 layout->addWidget(button4,12,0);}// Widget 类的析构函数,用于释放 ui 对象所占用的内存Widget::~Widget(){ delete ui;}
设置 QGridLayout 中元素的大小比例 + 设置垂直方向的拉伸系数
#include \"widget.h\"#include \"ui_widget.h\"#include // 引入 QPushButton 类,用于创建按钮控件#include // 引入 QGridLayout 类,用于创建网格布局管理器// Widget 类的构造函数,接收一个 QWidget 类型的指针作为参数,用于指定父窗口Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); // 初始化用户界面,将.ui 文件中设计的界面加载到当前 Widget 中 // 网格布局部分:创建六个按钮对象,并设置按钮的文本 QPushButton* button1 = new QPushButton(\"按钮1\"); QPushButton* button2 = new QPushButton(\"按钮1\"); QPushButton* button3 = new QPushButton(\"按钮2\"); QPushButton* button4 = new QPushButton(\"按钮2\"); QPushButton* button5 = new QPushButton(\"按钮3\"); QPushButton* button6 = new QPushButton(\"按钮3\"); // 创建一个网格布局管理器对象 layout,并指定当前 Widget 为其父对象 QGridLayout* layout = new QGridLayout(this); // 将按钮添加到网格布局的指定位置 // addWidget(QWidget *widget, int row, int column) 函数用于将控件添加到网格布局的指定行和列 // 第一个参数是要添加的控件,第二个参数是行索引(从 0 开始),第三个参数是列索引(从 0 开始) layout->addWidget(button1, 0, 0); // 将 button1 添加到第 0 行第 0 列 layout->addWidget(button2, 0, 1); // 将 button2 添加到第 0 行第 1 列 layout->addWidget(button3, 1, 0); // 将 button3 添加到第 1 行第 0 列 layout->addWidget(button4, 1, 1); // 将 button4 添加到第 1 行第 1 列 layout->addWidget(button5, 2, 0); // 将 button5 添加到第 2 行第 0 列 layout->addWidget(button6, 2, 1); // 将 button6 添加到第 2 行第 1 列 // setColumnStretch(int column, int stretch) 函数用于设置指定列的拉伸系数 // 第一个参数是列索引(从 0 开始),第二个参数是拉伸系数 // 拉伸系数决定了在布局空间改变时,该列相对于其他列的伸缩比例 // 这里设置第 0 列的拉伸系数为 5,第 1 列的拉伸系数为 3 layout->setColumnStretch(0, 5); layout->setColumnStretch(1, 3); // setRowStretch(int row, int stretch) 函数用于设置指定行的拉伸系数 // 第一个参数是行索引(从 0 开始),第二个参数是拉伸系数 // 拉伸系数决定了在布局空间改变时,该行相对于其他行的伸缩比例 // 需要注意的是,要使行拉伸生效,控件的大小策略需要设置为可扩展的 // QSizePolicy::Expanding 表示控件的尺寸可以根据可用空间进行调整 // 因为控件默认的大小策略是自适应的,所以需要手动打开扩展限制 // 以下代码被注释掉了,作用是将所有按钮的水平和垂直方向的大小策略设置为可扩展 // button1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // button2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // button3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // button4->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // button5->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // button6->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // 以下代码被注释掉了,作用是设置每一行的拉伸系数 // 第 0 行的拉伸系数为 1,第 1 行的拉伸系数为 2,第 2 行的拉伸系数为 3 // layout->setRowStretch(0, 1); // layout->setRowStretch(1, 2); // layout->setRowStretch(2, 3);}// Widget 类的析构函数,用于释放 ui 对象所占用的内存Widget::~Widget(){ delete ui;}
3.6.4 表单布局(QFormLayout)
除了上述的布局管理器之外,Qt 还提供了 QFormLayout,属于是 QGridLayout 的特殊情况,专门用于实现两列表单的布局。这种表单布局多用于让用户填写信息的场景,左侧列为提示,右侧列为输入框。
使用 QFormLayout 创建表单
#include \"widget.h\"#include \"ui_widget.h\"#include // 引入 QPushButton 类,用于创建按钮控件#include // 引入 QLineEdit 类,用于创建单行文本输入框控件#include // 引入 QFormLayout 类,用于创建表单布局管理器#include // 引入 QLabel 类,用于创建标签控件// Widget 类的构造函数,接收一个 QWidget 类型的指针作为参数,用于指定父窗口Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); // 初始化用户界面,将.ui 文件中设计的界面加载到当前 Widget 中 // 运用表单布局创建一个表单 // 创建一个表单布局管理器对象 layout,并指定当前 Widget 为其父对象 QFormLayout* layout = new QFormLayout(this); // 创建三个标签控件,分别用于显示表单的提示信息 QLabel* label1 = new QLabel(\"姓名\"); QLabel* label2 = new QLabel(\"年龄\"); QLabel* label3 = new QLabel(\"身份证号\"); // 创建三个单行文本输入框控件,用于用户输入信息 QLineEdit* line1 = new QLineEdit(); QLineEdit* line2 = new QLineEdit(); QLineEdit* line3 = new QLineEdit(); // 将标签和对应的文本输入框添加到表单布局中 // addRow(QLabel *label, QWidget *field) 函数用于将一个标签和一个控件作为一行添加到表单布局中 // 第一个参数是标签控件,第二个参数是对应的输入控件 layout->addRow(label1, line1); // 将“姓名”标签和对应的文本输入框添加到第一行 layout->addRow(label2, line2); // 将“年龄”标签和对应的文本输入框添加到第二行 layout->addRow(label3, line3); // 将“身份证号”标签和对应的文本输入框添加到第三行 // 通过表单创建一个按钮 // 创建一个按钮控件,设置按钮的文本为“确认” QPushButton* button = new QPushButton(\"确认\"); // 将按钮添加到表单布局的新行中 // 当第一个参数为 nullptr 时,表示该行不显示标签,只显示后面的控件 layout->addRow(nullptr, button);}// Widget 类的析构函数,用于释放 ui 对象所占用的内存Widget::~Widget(){ delete ui;}
3.6.5 Spacer
使用布局管理器的时候,可能需要在控件之间,添加一段空白,就可以使用 QSpacerItem 来表示。核心属性包括 width(宽度)、height(高度)、hData(水平方向的 sizePolicy,包含如 QSizePolicy::Minimum(控件的最小尺寸为固定值,布局时不会超过该值)等多种选项 )、vData(垂直方向的 sizePolicy,选项同 hData)。
创建一组左右排列的按钮并添加 spacer
#include \"widget.h\"#include \"ui_widget.h\"#include // 引入水平布局类,用于创建水平方向的布局管理器#include // 引入按钮类,用于创建按钮控件#include // 引入空白间隔项类,用于在布局中添加空白间隔// Widget 类的构造函数,接收一个 QWidget 类型的指针作为参数,用于指定父窗口Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); // 初始化用户界面,将.ui 文件中设计的界面加载到当前 Widget 中 // 创建两个按钮对象,并分别设置它们的显示文本 QPushButton* button1 = new QPushButton(\"按钮一\"); QPushButton* button2 = new QPushButton(\"按钮二\"); // 创建一个水平布局管理器对象 layout,并指定当前 Widget 为其父对象 QHBoxLayout* layout = new QHBoxLayout(this); // 第一种添加空白间隔的方法 // 创建一个空白间隔项对象 spaceer,设置其宽度为 100 像素,高度为 10 像素 QSpacerItem* spaceer = new QSpacerItem(100, 10); // 将按钮 1 添加到水平布局中 layout->addWidget(button1); // 将空白间隔项添加到水平布局中,这样按钮 1 和后续添加的控件之间会有一个空白间隔 layout->addSpacerItem(spaceer); // 第二种添加空白间隔的方法 // 直接创建一个空白间隔项并添加到布局中,宽度为 100 像素,高度为 10 像素 // 这里被注释掉了,若使用这种方式,就无需前面创建 spaceer 对象的操作 // layout->addItem(new QSpacerItem(100, 10)); // 将按钮 2 添加到水平布局中 layout->addWidget(button2);}// Widget 类的析构函数,用于释放 ui 对象所占用的内存Widget::~Widget(){ delete ui;}