当前位置: 首页 > news >正文

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 () 则能设置其是否可用。禁用状态下的控件不能接收用户输入事件,且外观通常呈灰色。在实际应用中,可通过按钮切换其他按钮的禁用状态,如在一个登录界面中,当用户未阅读并勾选协议时,提交按钮可设置为禁用状态。

API说明
isEnabled()获取到控件的可用状态
setEnabled设置控件是否可使用。true 表示可用,false 表示禁用


geometry 属性在控制控件位置和尺寸方面非常关键。可通过 geometry () 获取控件的位置和尺寸,setGeometry () 进行设置。例如,在开发一个拼图游戏时,可利用该属性精确控制每个拼图块的位置和大小,实现拼图的交互逻辑。

API说明
geometry()获取到控件的位置和尺寸。返回结果是一个 QRect,包含了 x, y, width, height。其中 x, y 是左上角的坐标
setGeometry(QRect)设置控件的位置和尺寸,可直接设置一个 QRect
setGeometry(int x, int y, int width, int height)设置控件的位置和尺寸,分别设置 x、y 坐标以及宽度、高度

控制按钮的位置

这个代码有点长,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"
#include<windows.h>
Widget::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 中,实现路径无关性。

API说明
windowIcon()获取到控件的窗口图标,返回 QIcon 对象
setWindowIcon(const QIcon& icon)设置控件的窗口图标,参数为 QIcon 类型的图标对象

设置窗口标题

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 运行时工作目录不同),这些问题都可能导致资源丢失或无法访问。

 
  1. qrc 机制的工作原理:qrc 文件用 XML 记录硬盘上的文件和对应的随意指定的资源名称,应用程序通过资源名称来访问这些资源。在构建程序的过程中,Qt 会把资源文件的二进制数据转成 cpp 代码,编译到 exe 中,从而使依赖的资源变得 “路径无关” 。这意味着无论 exe 被复制到哪个目录下,都能确保访问到资源文件。比如在设置窗口图标时,使用 qrc 管理图片作为图标,即使程序在不同目录运行,图标也能正常显示。
  2. qrc 机制的使用方法:在 Qt 开发中,使用 qrc 机制管理资源,首先要右键项目创建一个 Qt Resource File(qrc 文件),并给文件命名(不能带中文)。接着在 qrc 编辑器中添加前缀,前缀可理解为 “目录”,它决定了后续在代码中访问资源的方式,如设置前缀为 “/” 。之后在资源编辑器中点击 add Files 添加资源文件,添加的文件必须在 qrc 文件的同级目录或其子目录中。在代码中访问资源时,使用 “:” 作为开头,表示从 qrc 中读取资源,然后是配置的前缀和资源名称。例如,若资源文件 rose.jpg 添加到 qrc 中,且前缀为 “/”,在代码中使用 QIcon icon (":/rose.jpg"); 即可访问该图片资源并设置为窗口图标。
  3. qrc 机制的优缺点:qrc 机制的优点是确保了图片、字体、声音等资源能够真正做到 “目录无关”,无论程序如何拷贝、运行,都不会出现资源丢失的情况 。缺点是不适合管理体积大的资源,如果资源比较大(比如是几个 MB 的文件),或者资源特别多,生成的最终的 exe 体积就会比较大,程序运行消耗的内存也会增大,程序编译的时间也会显著增加。

访问这个文件

QIcon是 Qt 框架中用于表示图标的类,它可以管理不同尺寸和不同状态(如正常、禁用、激活等)的图标图像。借助QIcon,你能够在应用程序里方便地使用图标,像设置窗口图标、按钮图标等


windowOpacity

API说明
windowOpacity()获取控件的不透明数值,返回值为 float 类型,取值范围在 0.0 到 1.0 之间。其中 0.0 表示全透明,1.0 表示完全不透明
setWindowOpacity(float n)设置控件的不透明数值,参数 n 为 float 类型,取值范围需在 0.0 到 1.0 之间

调整窗⼝透明度

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::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

API说明
cursor()获取当前 widget 的 cursor 属性,返回 QCursor 对象。当鼠标悬停在该 widget 上时,会显示对应的形状
setCursor(const QCursor& cursor)设置该 widget 光标的形状,仅在鼠标停留在该 widget 上时生效
QGuiApplication::setOverrideCursor(const QCursor& cursor)设置全局光标的形状,对整个程序中的所有 widget 都会生效,会覆盖 setCursor 设置的内容

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

API说明
font()获取当前 widget 的字体信息,返回 QFont 对象
setFont(const QFont& font)设置当前 widget 的字体信息

qfont

属性说明
family字体家族,比如 “楷体”“宋体”“微软雅黑” 等
pointSize字体大小
weight字体粗细,以数值方式表示粗细程度,取值范围为 [0, 99],数值越大,字体越粗
bold是否加粗。设置为 true,相当于 weight 为 75;设置为 false,相当于 weight 为 50
italic是否倾斜
underline是否带有下划线
strikeOut是否带有删除线


toolTip(鼠标悬停提示)

API说明
setToolTip设置 toolTip,当鼠标悬停在该 widget 上时会显示提示说明
setToolTipDuration设置 toolTip 提示的时间,单位为 ms,时间到后 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

API说明
focusPolicy()获取该 widget 的焦点策略(focusPolicy),返回值类型为 Qt::FocusPolicy
setFocusPolicy(Qt::FocusPolicy policy)设置 widget 的焦点策略,参数为 Qt::FocusPolicy 类型的值

Qt::FocusPolicy 是 Qt 框架中用于表示控件焦点策略的一个枚举类型:

枚举值说明
Qt::NoFocus控件不会接收键盘焦点
Qt::TabFocus控件可以通过 Tab 键接收焦点
Qt::ClickFocus控件在鼠标点击时接收焦点
Qt::StrongFocus控件可以通过 Tab 键和鼠标点击接收焦点(默认值)
Qt::WheelFocus类似于 Qt::StrongFocus,同时控件也可通过鼠标滚轮获取到焦点(新增的选项,一般很少使用)

什么是焦点策略?

在图形用户界面(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文件看)

属性说明
text按钮中所显示的文本内容
icon按钮中所显示的图标
iconSize按钮中图标呈现的尺寸大小
shortCut与该按钮相对应的快捷键,按下此快捷键可触发按钮功能
autoRepeat按钮是否具备重复触发的特性。当鼠标左键按住不放时,若设为 true,会持续产生鼠标点击事件;若设为 false,则需释放鼠标后再次按下,才会产生点击事件(类似于游戏手柄上的 “连发” 效果)
autoRepeatDelay重复触发的延时时间,即按住按钮多长时间后开始进入重复触发状态
autoRepeatInterval重复触发的周期,即相邻两次重复触发之间的时间间隔
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.pngui->object->setIcon(QIcon(":/img/doghead.png"));// 设置该对象图标的尺寸为 60x60 像素ui->object->setIconSize(QSize(60,60));// 上下左右控制按钮的图标设置// 上按钮// 设置上按钮的图标为资源文件中的 up.pngui->pushButton_up->setIcon(QIcon(":/img/up.png"));// 设置上按钮图标的尺寸为 30x30 像素ui->pushButton_up->setIconSize(QSize(30,30));// 下按钮// 设置下按钮的图标为资源文件中的 down.pngui->pushButton_down->setIcon(QIcon(":/img/down.png"));// 设置下按钮图标的尺寸为 30x30 像素ui->pushButton_down->setIconSize(QSize(30,30));// 左按钮// 设置左按钮的图标为资源文件中的 left.pngui->pushButton_left->setIcon(QIcon(":/img/left.png"));// 设置左按钮图标的尺寸为 30x30 像素ui->pushButton_left->setIconSize(QSize(30,30));// 右按钮// 设置右按钮的图标为资源文件中的 right.pngui->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 + Wui->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(是否排他)。以选择性别为例,可通过设置单选按钮的槽函数,根据用户选择更新界面显示。同时,还可实现单选框分组,使不同组之间的单选按钮互不影响,比如在一个问卷调查界面中,不同问题的单选选项可进行分组设置。

属性说明
checkable表示该按钮(或控件)是否具有可被选中的特性。若设置为 true,则按钮可以处于选中或未选中状态;若设置为 false,则按钮不能被选中。
checked用于判断按钮是否已经处于被选中的状态。需要注意的是,只有当 checkable 属性为 true 时,checked 属性才有意义,即 checkable 是 checked 的前提条件。
autoExclusive该属性决定按钮是否具有排他性。当设置为 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 的区别;

信号说明
clicked表示一次 “点击” 操作,通常是鼠标点击按钮后触发,涵盖了鼠标按下并释放的完整过程
pressed表示鼠标 “按下” 按钮的动作,即鼠标按键接触到按钮时触发该信号
released表示鼠标 “释放” 按钮的动作,也就是鼠标按键从按钮上抬起时触发此信号
toggled表示按钮状态切换,一般用于具有可切换状态(如选中 / 未选中)的按钮,当按钮的状态发生改变时触发该信号
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
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 <QButtonGroup>
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 <QDebug>
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 可用于显示新闻标题、内容和相关图片,并通过设置属性实现美观的排版。

属性说明具体取值及解释
textQLabel 中的文本内容
textFormat文本的格式<ul><li>Qt::PlainText:纯文本</li><li>Qt::RichText:富文本(支持 HTML 标签)</li><li>Qt::MarkdownText:Markdown 格式</li><li>Qt::AutoText:根据文本内容自动决定文本格式</li></ul>
pixmapQLabel 内部包含的图片
scaledContents控制内容是否自动拉伸填充 QLabel<ul><li>设为 true 表示内容自动拉伸填充 QLabel</li><li>设为 false 则不会自动拉伸</li></ul>
alignment文本的对齐方式,可设置水平和垂直方向的对齐
wordWrap控制内部文本是否自动换行<ul><li>设为 true 内部的文本会自动换行</li><li>设为 false 则内部文本不会自动换行</li></ul>
indent设置文本缩进,水平和垂直方向都生效
margin内部文本和边框之间的边距,上下左右四个方向同时有效
openExternalLinks是否允许打开一个外部的链接(当 QLabel 文本内容包含 url 的时候涉及到)<ul><li>设为 true 时,若文本包含链接可打开外部链接</li><li>设为 false 时,不允许打开外部链接</li></ul>
buddy给 QLabel 关联一个 “伙伴”,点击 QLabel 时能激活对应的伙伴例如伙伴如果是一个 QCheckBox,那么该 QCheckBox 就会被选中

显示不同格式的文本

显示图片

#include "widget.h"
#include "ui_widget.h"
#include <QResizeEvent>
#include <QDebug>
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()<<event->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 显示剩余时间。

属性说明具体取值及解释
intValueQLCDNumber 显示的数字值(类型为 int
valueQLCDNumber 显示的数字值(类型为 double),与 intValue 联动,如设置 value 为 1.5intValue 的值就是 2
digitCount用于设置 QLCDNumber 显示的数字位数
mode数字的显示形式<ul><li>QLCDNumber::Dec:十进制模式,显示常规的十进制数字,只有在此模式下才能显示小数点后的内容</li><li>QLCDNumber::Hex:十六进制模式,以十六进制格式显示数字</li><li>QLCDNumber::Bin:二进制模式,以二进制格式显示数字</li><li>QLCDNumber::Oct:八进制模式,以八进制格式显示数字</li></ul>
segmentStyle设置 QLCDNumber 的显示风格<ul><li>QLCDNumber::Flat:平面的显示风格,数字呈现在一个平坦的表面上</li><li>QLCDNumber::Outline:轮廓显示风格,数字具有清晰的轮廓和阴影效果</li><li>QLCDNumber::Filled:填充显示风格,数字被填充颜色并与背景区分开</li></ul>
smallDecimalPoint设置较小的小数点若设置为 true,则显示较小的小数点;设置为 false 则显示正常大小的小数点
特殊说明设置 value 和 intValue 的方法是 display,而不是 setValue 或者 setIntValue

实现倒计时功能

#include "widget.h"
#include "ui_widget.h"//QTimer 的 timeout 信号在其所属线程发射(默认与父对象线程一致)
#include <QTimer>
#include <QDebug>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建一个倒计时//显示10ui->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()<<"定时器";int value = ui->lcdNumber->intValue(); //intValue -- QLCDNumber 显⽰的数字值(int)//暂停定时器if(value <= 0) {t->stop();return;};//设置定时器的倒计时逻辑ui->lcdNumber->display(--value);}

这里qt是不能使用sleep的

  1. 界面假死:如果在主线程(即 GUI 线程)中使用 sleep 函数,会导致整个应用程序的界面无法响应,因为主线程负责处理界面的绘制、用户输入等操作。当 sleep 函数使主线程挂起时,界面无法更新,给用户的感觉就是程序卡死了。例如,在一个按钮点击事件处理函数中使用 sleep(5),在这 5 秒钟内,窗口无法移动、最小化,按钮也无法再次点击等。

  2. 跨平台问题:标准 C/C++ 库中的 sleep 函数在不同操作系统上的实现和行为可能略有差异(如 Windows 上是 Sleep),这会影响代码的跨平台性。而 Qt 本身提供了更合适的、跨平台的处理等待和延时的方式。


3.2.3 ProgressBar

QProgressBar 用于展示任务进度,核心属性包括 minimum、maximum、value、alignment、textVisible 等。可通过设置这些属性控制进度条的最小值、最大值、当前值、文本对齐方式和数字是否可见等。在实际开发中,进度条的取值通常根据任务实际进度设置,如在文件上传或下载过程中,实时更新进度条以反馈进度情况。

属性说明具体取值及解释
minimum进度条的最小值,即进度条所能表示的最小数值无,为一个整数值
maximum进度条的最大值,即进度条所能表示的最大数值无,为一个整数值,且需大于 minimum
value进度条的当前值,反映进度条当前所处的进度状态取值范围在 minimum 和 maximum 之间的一个整数值
alignment文本在进度条中的对齐方式Qt::AlignLeft:左对齐Qt::AlignRight:右对齐Qt::AlignCenter:居中对齐Qt::AlignJustify:两端对齐
textVisible用于设置进度条上显示的数字是否可见若为 true,则进度条上的数字可见;若为 false,则不可见
orientation表示进度条的方向,是水平还是垂直无,取值通常为表示水平或垂直方向的枚举值
invertAppearance决定进度条是否朝反方向增长进度若为 true,进度条从最大值向最小值方向增长;若为 false,则从最小值向最大值方向增长
textDirection文本的朝向,控制进度条上显示文本的方向无,根据具体设置决定文本朝向
format展示的数字格式,用于定义进度条上显示的内容形式

%p:表示进度的百分比(0-100)

%v:表示进度的数值(其范围在进度条的 minimum 到 maximum 之间)

%m:表示剩余时间(以毫秒为单位)

%t:表示总时间(以毫秒为单位)

设置进度条按时间增长 + 变红色的进度条

#include "widget.h"
#include "ui_widget.h"
#include <QTimer>// 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 等。通过这些属性和信号,可获取选中的日期,实现日期选择和相关操作。例如,在一个日程管理软件中,用户可通过日历选择日期,查看和安排当天的日程。

核心属性

属性说明
selectDate当前选中的日期
minimumDate最小日期
maximumDate最大日期
firstDayOfWeek每周的第一天(即日历的第一列)是周几
gridVisible是否显示表格的边框
selectionMode是否允许选择日期
navigationBarVisible日历上方标题是否显示
horizontalHeaderFormat日历上方标题显示的日期格式
verticalHeaderFormat日历第一列显示的内容格式
dateEditEnabled是否允许日期被编辑

重要信号

信号说明
selectionChanged(const QDate&)当选中的日期发生改变时发出,形参是一个 QDate 类型,保存了新选中的日期
activated(const QDate&)当双击一个有效的日期或者按下回车键时发出,形参是一个 QDate 类型,保存了选中的日期
currentPageChanged(int, int)当年份月份改变时发出,形参表示改变后的新年份和月份

获取选中的日期

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::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()<<date;//点击日期显示在label标签中ui->label->setText(date.toString());
}


3.3 输入类控件

3.3.1 Line Edit

QLineEdit 用于实现单行输入功能,核心属性包括 text、inputMask、maxLength 等,还有显示方式(echoMode)、光标位置(cursorPosition)、对齐方式(alignment)等属性。它还包含多个核心信号,如 cursorPositionChanged、editingFinished、returnPressed 等。在实际应用中,可用于录入个人信息,如姓名、密码、电话号码等,并通过设置输入掩码(inputMask)和验证器进行输入格式校验,确保用户输入的数据符合要求。

核心属性

属性说明
text输入框中的文本
inputMask输入内容格式约束
maxLength最大长度
frame是否添加边框
echoMode显示方式:
・QLineEdit::Normal :这是默认值,文本框会显示输入的文本。
・QLineEdit::Password :在这种模式下,输入的字符会被隐藏,通常用星号(*)或等号(=)代替。
・QLineEdit::NoEcho :在这种模式下,文本框不会显示任何输入的字符。
cursorPosition光标所在位置
alignment文字对齐方式,设置水平和垂直方向的对齐。
dragEnabled是否允许拖拽
readOnly是否是只读的 (不允许修改)
placeHolderText当输入框内容为空的时候,显示什么样的提示信息
clearButtonEnabled是否会自动显示出 “清除按钮”。

核心信号

属性说明
void cursorPositionChanged(int old, int new)当鼠标移动时发出此信号,old 为先前的位置,new 为新位置。
void editingFinished()当按返回或者回车键时,或者行编辑失去焦点时,发出此信号。
void returnPressed()当返回或回车键按下时发出此信号。如果设置了验证器,必须要验证通过,才能触发。
void selectionChanged()当选中的文本改变时,发出此信号。
void textChanged(const QString &text)当 QLineEdit 中的文本改变时,发出此信号,text 是新的文本。代码对文本的修改能够触发这个信号。
void textEdited(const QString &text)当 QLineEdit 中的文本改变时,发出此信号,text 是新的文本。代码对文本的修改不能触发这个信号。

录入个人信息

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
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()<<"姓名:"<< ui->lineEdit_name->text()<<"密码:"<< ui->lineEdit_passwd->text()<<"性别:"<< gender<<"电话号码"<< ui->lineEdit_phone->text();
}

使用正则表达式验证输入框的数据

类别详情
正则表达式文档https://learn.microsoft.com/zh-cn/previousversions/visualstudio/visual-studio-2008/ae5bf541(v=vs.90)?redirectedfrom=MSDN
正则表达式在线工具正则表达式语法测试工具 - 在线工具

#include "widget.h"
#include "ui_widget.h"
#include<QRegExpValidator>// 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 等核心信号。可用于获取多行输入框的内容,实现文本编辑和实时预览等功能。例如,在一个简单的文本编辑器中,用户可输入多行文本,进行格式编辑,程序实时显示编辑效果。

核心属性的表格:

属性说明
markdown输入框内持有的内容,支持 markdown 格式,能够自动的对 markdown 文本进行渲染成 html
html输入框内持有的内容,可以支持大部分 html 标签,包括 img 和 table 等
placeHolderText输入框为空时提示的内容
readOnly是否是只读的
undoRedoEnable是否开启 undo/redo 功能,按下 ctrl+z 触发 undo,按下 ctrl+y 触发 redo
autoFormating开启自动格式化
tabstopWidth按下缩进占多少空间
overwriteMode是否开启覆盖写模式
acceptRichText是否接收富文本内容
verticalScrollBarPolicy垂直方向滚动条的出现策略,包括 Qt::ScrollBarAsNeeded(根据内容自动决定是否需要滚动条,这是默认值)、Qt::ScrollBarAlwaysOff(总是关闭滚动条)、Qt::ScrollBarAlwaysOn(总是显示滚动条)
horizontalScrollBarPolicy水平方向滚动条的出现策略,包括 Qt::ScrollBarAsNeeded(根据内容自动决定是否需要滚动条,这是默认值)、Qt::ScrollBarAlwaysOff(总是关闭滚动条)、Qt::ScrollBarAlwaysOn(总是显示滚动条)

以下是核心信号的表格:

信号说明
textChanged()文本内容改变时触发
selectionChanged()选中范围改变时触发
cursorPositionChanged()光标移动时触发
undoAvailable(bool)可以进行 undo 操作时触发
redoAvailable(bool)可以进行 redo 操作时触发
copyAvaiable(bool)文本被选中 / 取消选中时触发

获取多行输入框的内容

验证输入框的各种信号

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);}Widget::~Widget()
{delete ui;
}//测试TexteEdit所有的信号void Widget::on_textEdit_textChanged()
{qDebug()<<"textChanged"<<ui->textEdit->toPlainText();
}//鼠标选中范围
void Widget::on_textEdit_selectionChanged()
{//接收返回的鼠标位置const QTextCursor& cursor = ui->textEdit->textCursor();//打印鼠标选中范围selecedTextqDebug()<<"selectionChanged"<<cursor.selectedText();
}//鼠标位置(字符个数来表示当前鼠标的位置)
void Widget::on_textEdit_cursorPositionChanged()
{const QTextCursor& cursor = ui->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 等。在实际应用中,可用于模拟点餐场景,从文件中加载选项等。比如在一个在线点餐系统中,用户通过下拉框选择菜品和饮料。

核心属性表格

属性说明
currentText当前选中的文本
currentIndex当前选中的条⽬下标,从 0 开始计算。如果当前没有条⽬被选中,值为 - 1
editable是否允许修改,设为 true 时,QComboBox 的⾏为就⾮常接近 QLineEdit ,也可以设置 validator
iconSize下拉框图标(⼩三⻆)的⼤⼩
maxCount最多允许有多少个条⽬

核心方法表格

方法说明
addItem(const QString&)添加⼀个条⽬
currentIndex()获取当前条⽬的下标,从 0 开始计算。如果当前没有条⽬被选中,值为 - 1
currentText()获取当前条⽬的⽂本内容

核心信号表格

信号说明
activated(int)当⽤⼾选择了⼀个选项时发出,相当于⽤⼾点开下拉框,并且⿏标划过某个选项,此时还没有确认做出选择
activated(const QString & text)当⽤⼾选择了⼀个选项时发出,相当于⽤⼾点开下拉框,并且⿏标划过某个选项,此时还没有确认做出选择
currentIndexChanged(int)当前选项改变时发出,此时⽤⼾已经明确的选择了⼀个选项,⽤⼾操作或者通过程序操作都会触发这个信号
currentIndexChanged(const QString & text)当前选项改变时发出,此时⽤⼾已经明确的选择了⼀个选项,⽤⼾操作或者通过程序操作都会触发这个信号
editTextChanged(const QString & text)当编辑框中的⽂本改变时发出(editable 为 true 时有效)

使用下拉框模拟买东西

从文件中加载下拉框的选项

  1. std::ifstream:这是 C++ 标准库 <fstream> 头文件中定义的一个类,用于实现从文件中读取数据的功能,即文件输入流。通过创建 std::ifstream 类的对象,并在构造函数中传入要打开的文件路径,就可以建立与该文件的连接,以便后续读取文件内容。
  2. is_open():这是 std::ifstream 类的成员函数。其作用是检查通过 std::ifstream 对象尝试打开的文件是否成功打开。如果文件成功打开,该函数返回 true;如果文件打开失败(例如文件不存在、权限不足等原因),则返回 false。通常在打开文件后会调用这个函数来判断文件是否可用,以避免在文件未成功打开的情况下进行无效的读取操作。
  3. close():这也是 std::ifstream 类的成员函数。当对文件的读取操作完成后,调用 close() 函数可以关闭之前通过 std::ifstream 对象与文件建立的连接,释放与该文件相关的系统资源(如文件句柄等)。关闭文件是良好的编程习惯,确保资源得到合理管理,防止出现资源泄漏等问题。
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <fstream>
#include <string>
#include <iostream>// Widget 类的构造函数,parent 为父窗口指针,默认为 nullptr
Widget::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() << "无法打开文件";// 关闭文件流(虽然文件未成功打开,但为了代码完整性关闭)file.close();// 直接返回,不再执行后续读取文件的操作return;}// 用于存储从文件中读取的每一行内容std::string line;// 使用 std::getline 函数逐行读取文件内容,直到文件结束while (std::getline(file, line)) {// 将 std::string 类型的 line 转换为 QString 类型,然后添加到下拉列表中ui->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 等。在实际应用中,可用于调整购物车中商品的份数,如在电商购物车界面中,用户可通过微调框增加或减少商品数量。

核心属性表格

属性说明
value存储的数值
singleStep每次调整的 “步长”,即按下一次按钮数据变化的量
displayInteger数字的进制,例如设为 10,则按 10 进制表示;设为 2 则按 2 进制表示
minimum最小值
maximum最大值
suffix后缀
prefix前缀
wrapping是否允许换行
frame是否带边框
alignment文字对齐方式
readOnly是否允许修改
buttonSymbol按钮上的图标,有三种形式:UpDownArrows(上下箭头形式)、PlusMinus(加减号形式)、NoButtons(没有按钮)
accelerated(加速的)按下按钮时是否为快速调整模式
correctionMode输入有误时的修正方式,有两种:QAbstractSpinBox::CorrectToPreviousValue(如果用户输入了一个无效的值,SpinBox 会恢复为上一个有效值)、QAbstractSpinBox::CorrectToNearestValue(如果用户输入了一个无效的值,SpinBox 会恢复为最接近的有效值)
keyboardTrack是否开启键盘跟踪,设为 true 时,每次在输入框输入一个数字,都会触发一次 valueChanged () 和 textChanged () 信号;设为 false 时,只有在最终按下 enter 或者输入框失去焦点,才会触发 valueChanged () 和 textChanged () 信号

核心信号表格

信号说明
textChanged(QString)微调框的文本发生改变时会触发,参数 QString 带有前缀和后缀
valueChanged(int)微调框的文本发生改变时会触发,参数 int 表示当前的数值

调整麦当劳购物车中的份数

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>// Widget 类的构造函数,parent 为父窗口指针,默认值为 nullptr
Widget::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 到 10ui->spinBox->setRange(1, 10);// 设置第二个自旋框 spinBox_2 的取值范围为 1 到 10ui->spinBox_2->setRange(1, 10);// 设置第三个自旋框 spinBox_3 的取值范围为 1 到 10ui->spinBox_3->setRange(1, 10);
}// Widget 类的析构函数,用于释放 ui 对象所占用的内存
Widget::~Widget()
{delete ui;
}// 当名为 pushButton 的按钮被点击时,会触发该槽函数
void Widget::on_pushButton_clicked()
{// 使用 qDebug 输出当前各个下拉框选中的文本以及对应的自旋框中的文本// 输出格式为:下拉框选中的文本 : 自旋框中的文本qDebug()<< ui->comboBox->currentText() << ":" << ui->spinBox->text()<< ui->comboBox_2->currentText() << ":" << ui->spinBox_2->text()<< ui->comboBox_3->currentText() << ":" << ui->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 个小时的时间点。

核心属性表格

属性说明
dateTime时间日期的值,形如 2000/1/1 0:00:00
date单纯日期的值,形如 2001/1/1
time单纯时间的值,形如 0:00:00
displayFormat时间日期格式,形如 yyyy/M/d H:mm 。其中 y 表示年份,M 表示月份,d 表示日期,H 表示小时,m 表示分钟,s 表示秒。注意格式化符号的含义使用时需查询,不同语言 / 库设定规则有差异
minimumDateTime最小时间日期
maximumDateTime最大时间日期
timeSpec时间规范,有三种取值:Qt::LocalTime(显示本地时间)、Qt::UTC(显示协调世界时(UTC))、Qt::OffsetFromUTC(显示相对于 UTC 的偏移量 (时差))

核心信号表格

信号说明
dateChanged(QDate)日期改变时触发
timeChanged(QTime)时间改变时触发
dateTimeChanged(QDateTime)时间日期任意一个改变时触发

实现日期计算器

        

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>// Widget 类的构造函数,parent 为父窗口指针,默认值为 nullptr
Widget::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_timeQDateTime old_time =  ui->dateTimeEdit->dateTime();// 从 dateTimeEdit_2 控件中获取日期时间值,并赋值给 new_timeQDateTime new_time = ui->dateTimeEdit_2->dateTime();// 计算天数// daysTo 返回从这个日期时间到另一个日期时间的天数。// 天数的计算方法是统计从这个日期时间到另一个日期时间之间经历午夜(凌晨零点)的次数。这就意味着// 从当天 23:55 到次日 0:05 这样 10 分钟的时间差算作一天。// 这里注释掉了原来有问题的代码,因为 daysTo 函数计算的是日期之间的天数差,不是时间差的天数// int day = old_time.daysTo(new_time);//bug// qDebug() << day;// 计算小时数// secsTo 函数返回从 old_time 到 new_time 的秒数差值int hour = old_time.secsTo(new_time);// 计算天数,先将总秒数转换为小时数,再除以 24 得到天数int day = (hour / 3600) / 24;// 计算剩余的小时数,先将总秒数转换为小时数,再对 24 取余得到剩余小时数hour = (hour / 3600) % 24;// 构建显示字符串,包含相差的天数和小时数QString con = QString("相差:") + QString::number(day) + QString("天") + QString::number(hour) + QString("小时");// 将构建好的字符串设置到 label 控件上显示ui->label->setText(con);
}


3.3.6 Dial

QDial 表示旋钮,核心属性有 value、minimum、maximum 等,核心信号有 valueChanged、rangeChanged 等。在实际应用中,可用于调整窗口透明度等功能,如在一个图像编辑软件中,通过旋转旋钮调整图片的透明度。

核心属性表格

属性说明
value持有的数值
minimum最小值
maximum最大值
singleStep按下方向键的时候改变的步长
pageStep按下 pageUp/pageDown 的时候改变的步长
sliderPosition界面上旋钮显示的初始位置
tracking外观是否会跟踪数值变化,默认值为 true,一般不需要修改
wrapping是否允许循环调整,即数值如果超过最大值,是否允许回到最小值(调整过程能否 “套圈”)
notchesVisible是否显示刻度线
notchTarget刻度线之间的相对位置,数字越大,刻度线越稀疏

核心信号表格

信号说明
valueChanged(int)数值改变时触发
rangeChanged(int, int)范围变化时触发(两个参数分别表示新的最小值和最大值)

调整窗口透明度

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>// Widget类的构造函数,parent为指向父窗口的指针,默认值为nullptr
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{// 调用setupUi函数,将UI设计器中创建的界面布局应用到当前窗口ui->setupUi(this);// 设置拨号盘(dial)的初始值为100ui->dial->setValue(100);// 设置拨号盘(dial)的最小值为0ui->dial->setMinimum(0);// 设置拨号盘(dial)的最大值为100ui->dial->setMaximum(100);// 设置拨号盘(dial)允许循环转动,即当数值超过最大值时回到最小值ui->dial->setWrapping(true);// 使拨号盘(dial)显示刻度线ui->dial->setNotchesVisible(true);// 设置拨号盘(dial)刻度线之间的相对位置,值越小刻度线越密集,这里设置为0.1ui->dial->setNotchTarget(0.1);
}// Widget类的析构函数,用于释放ui对象所占用的内存
Widget::~Widget()
{delete ui;
}// 当拨号盘(dial)的值发生变化时,会触发这个槽函数
// value参数表示拨号盘当前的数值
void Widget::on_dial_valueChanged(int value)
{// 使用qDebug输出当前拨号盘的数值qDebug() << value;// 构建一个字符串,用于显示当前的透明度设置信息QString context = QString("当前调透明度") + QString::number(value) + QString("%");// 将构建好的字符串设置到标签(label)上进行显示ui->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 等。在实际应用中,可用于调整窗口大小,通过自定义快捷键调整滑动条位置等。比如在一个视频播放软件中,用户可通过滑动条调整视频音量或播放进度。

核心属性表格

属性说明
value持有的数值
minimum最小值
maximum最大值
singleStep按下方向键时数值改变的步长
pageStep按下 pageUp/pageDown 键时数值改变的步长
sliderPosition滑动条显示的初始位置
tracking外观是否会跟踪数值变化,默认值为 true,一般无需修改
orientation滑动条的方向,可设置为水平或垂直
invertedAppearance是否要翻转滑动条的方向
tickPosition刻度的位置
tickInterval刻度的密集程度

核心信号表格

信号说明
valueChanged(int)当滑动条的数值发生改变时触发,参数 int 表示当前的数值
rangeChanged(int, int)当滑动条的取值范围(最小值和最大值)发生变化时触发,两个参数分别表示新的最小值和最大值

调整窗口大小

#include "widget.h"
#include "ui_widget.h"// Widget 类的构造函数,parent 为指向父窗口的指针,默认值为 nullptr
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{// 调用 setupUi 函数,将 UI 设计器中创建的界面布局应用到当前窗口ui->setupUi(this);// 设置垂直滑动条(verticalSlider)的属性// 设置垂直滑动条的最小值为 500ui->verticalSlider->setMinimum(500);// 设置垂直滑动条的最大值为 2000ui->verticalSlider->setMaximum(2000);// 设置垂直滑动条的初始值为 600ui->verticalSlider->setValue(600);// 设置水平滑动条(horizontalSlider)的属性// 设置水平滑动条的最小值为 500ui->horizontalSlider->setMinimum(500);// 设置水平滑动条的最大值为 2000ui->horizontalSlider->setMaximum(2000);// 设置水平滑动条的初始值为 800ui->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<QShortcut>// Widget类的构造函数,parent为父窗口指针,默认值为nullptr
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{// 调用setupUi函数,将UI设计器中设计好的界面布局应用到当前窗口ui->setupUi(this);// 设置水平滑动条的最小值为1ui->horizontalSlider->setMinimum(1);// 设置水平滑动条的最大值为100ui->horizontalSlider->setMaximum(100);// 设置水平滑动条每次按方向键时改变的步长为3ui->horizontalSlider->setSingleStep(3);// 通过使用快捷键来实现移动// 创建两个QShortcut对象,用于处理快捷键操作,this表示该快捷键对象的父对象为当前WidgetQShortcut *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 多元素控件

比较维度Q*ViewQ*Widget
设计模式基于 MVC 设计模式,视图和数据模型分离,自身不持有数据是 QTableView 的子类,对 Model 进行了封装
数据管理需用户手动创建 Model 对象并关联,通过修改 Model 影响显示,反之亦然,实现双向绑定无需手动创建 Model 对象,可直接添加数据
灵活性与扩展性灵活性和扩展性强,可自定义数据模型和视图代理,实现复杂表格显示与交互灵活性和扩展性较差,内部封装数据模型,难以直接定制,处理复杂表格需求可能受限
3.4.1 List Widget

QListWidget 用于显示纵向列表,核心属性包括 currentRow、count、sortingEnabled 等,核心方法有 addItem、currentItem、setCurrentItem 等,核心信号有 currentItemChanged、currentRowChanged 等。在实际应用中,可用于展示多个选项,实现元素的添加、删除和选中操作。例如,在一个待办事项列表中,用户可添加新的事项,选中并删除已完成的事项。

QListWidget 核心属性

属性说明
currentRow当前被选中的行数
count列表的总行数
sortingEnabled是否允许对列表内容进行排序
isWrapping是否允许内容换行显示
itemAlignment元素的对齐方式
selectRectVisible被选中元素的矩形框是否可见
spacing元素之间的间距

QListWidget 核心方法

方法说明
addItem(const QString& label)
addItem(QListWidgetItem *item)
向列表中添加元素,前者通过字符串添加,后者通过 QListWidgetItem 对象添加
currentItem()返回 QListWidgetItem* 类型,表示当前选中的元素
setCurrentItem(QListWidgetItem* item)设置当前选中的元素
setCurrentRow(int row)设置选中指定行的元素
insertItem(const QString& label, int row)
insertItem(QListWidgetItem *item, int row)
在指定位置插入元素,前者用字符串,后者用 QListWidgetItem 对象
item(int row)返回 QListWidgetItem* 类型,表示指定行的元素
takeItem(int row)删除指定行的元素,并返回被删除的 QListWidgetItem* 对象

QListWidget 核心信号

信号方法说明
currentItemChanged(QListWidgetItem* current, QListWidgetItem* old)选中元素发生变化时触发,参数分别为当前选中元素和之前选中的元素
currentRowChanged(int)选中元素发生变化时触发,参数为当前选中元素的行数
itemClicked(QListWidgetItem* item)点击某个元素时触发
itemDoubleClicked(QListWidgetItem* item)双击某个元素时触发
itemEntered(QListWidgetItem* item)鼠标进入某个元素时触发

QListWidgetItem 核心方法

方法说明
setFont设置元素的字体
setIcon设置元素的图标
setHidden设置元素是否隐藏
setSizeHint设置元素的尺寸
setSelected设置元素是否被选中
setText设置元素显示的文本
setTextAlignment设置元素文本的对齐方式

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>// Widget类的构造函数,parent为父窗口指针,默认为nullptr
Widget::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()<<"当前选中:"<<current->text();// 打印上一个选中项的文本内容qDebug()<<"上一个:"<<previous->text();}
}


3.4.2 Table Widget

QTableWidget 用于显示表格,包含若干行和列,每个单元格是一个 QTableWidgetItem 对象。它具有丰富的核心方法,如 item、setItem、currentItem 等,以及多个核心信号,如 cellClicked、cellDoubleClicked 等。在实际应用中,可用于展示和编辑表格数据,如在一个学生成绩管理系统中,以表格形式展示学生的学号、姓名、成绩等信息,并支持数据的添加、删除和修改。

QTableWidget 核心方法

方法说明
item(int row, int column)依据行号和列号获取指定的 QTableWidgetItem*
setItem(int row, int column, QTableWidget*)按照行号和列号设置表格中的元素
currentItem()返回被选中的元素 QTableWidgetItem*
currentRow()返回被选中元素所在的行号
currentColumn()返回被选中元素所在的列号
row(QTableWidgetItem*)获取指定 item 所在的行号
column(QTableWidgetItem*)获取指定 item 所在的列号
rowCount()获取表格的行数
columnCount()获取表格的列数
insertRow(int row)在第 row 行处插入新行
insertColumn(int column)在第 column 列处插入新列
removeRow(int row)删除第 row 行
removeColumn(int column)删除第 column 列
setHorizontalHeaderItem(int column, QTableWidget*)设置指定列的表头
setVerticalHeaderItem(int row, QTableWidget*)设置指定行的表头

QTableWidget 核心信号

信号说明
cellClicked(int row, int column)点击单元格时触发
cellDoubleClicked(int row, int column)双击单元格时触发
cellEntered(int row, int column)鼠标进入单元格时触发
currentCellChanged(int row, int column, int previousRow, int previousColumn)选中不同单元格时触发

QTableWidgetItem 核心方法

方法说明
row()获取当前所在的行号
column()获取当前所在的列号
setText(const QString&)设置文本内容
setTextAlignment(int)设置文本对齐方式
setIcon(const QIcon&)设置图标
setSelected(bool)设置是否被选中
setSizeHints(const QSize&)设置尺寸
setFont(const QFont&)设置字体

使用 QTableWidget 简单理解就是一个二维表格

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>// 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()<<col;// 在表格的末尾插入一列新列ui->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 核心方法

方法说明
clear()清空所有子节点
addTopLevelItem(QTreeWidgetItem* item)新增顶层节点
topLevelItem(int index)获取指定下标的顶层节点
topLevelItemCount()获取顶层节点个数
indexOfTopLevelItem(QTreeWidgetItem* item)查询指定节点在顶层节点中的下标
takeTopLevelItem(int index)删除指定的顶层节点,返回被删除的 QTreeWidgetItem*
currentItem()获取当前选中的节点,返回 QTreeWidgetItem*
setCurrentItem(QTreeWidgetItem* item)选中指定节点
setExpanded(bool)展开 / 关闭节点
setHeaderLabel(const QString& text)设置 TreeWidget 的 header 名称

QTreeWidget 核心信号

信号说明
currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* old)切换选中元素时触发
itemClicked(QTreeWidgetItem* item, int col)点击元素时触发
itemDoubleClicked(QTreeWidgetItem* item, int col)双击元素时触发
itemEntered(QTreeWidgetItem* item, int col)鼠标进入元素时触发
itemExpanded(QTreeWidgetItem* item)元素被展开时触发
itemCollapsed(QTreeWidgetItem* item)元素被折叠时触发

QTreeWidgetItem 核心属性

属性说明
text持有的文本
textAlignment文本对齐方式
icon持有的图标
font文本字体
hidden是否隐藏
disabled是否禁用
expanded是否展开
sizeHint尺寸大小
selected是否选中

QTreeWidgetItem 核心方法

方法说明
addChild(QTreeWidgetItem* child)新增子节点
childCount()子节点的个数
child(int index)获取指定下标的子节点,返回 QTreeWidgetItem*
takeChild(int index)删除对应下标的子节点
removeChild(QTreeWidgetItem* child)删除对应的子节点
parent()获取该元素的父节点

使用 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当前选中了第几个标签页(从 0 开始计算)
currentTabText当前选中的标签页的文本
currentTabName当前选中的标签页的名字
currentTabIcon当前选中的标签页的图标
currentTabToolTip当前选中的标签页的提示信息
tabsCloseable标签页是否可以关闭
movable标签页是否可以移动

核心信号及其说明

信号说明
currentChanged(int)在标签页发生切换时触发,参数为被点击的选项卡编号
tabBarClicked(int)在点击选项卡的标签条的时候触发,参数为被点击的选项卡编号
tabBarDoubleClicked(int)在双击选项卡的标签条的时候触发,参数为被点击的选项卡编号
tabCloseRequest(int)在标签页关闭时触发,参数为被关闭的选项卡编号

使用标签页管理多组控件

#include "widget.h"
#include "ui_widget.h"
#include <QLabel>// 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对象,每个标签页本质上就是一个QWidgetQWidget* 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对象mmQLabel *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(相邻元素之间的间距) 。

属性说明
layoutLeftMargin左侧边距
layoutRightMargin右侧边距
layoutTopMargin上方边距
layoutBottomMargin下方边距
layoutSpacing相邻元素之间的间距
#include "widget.h"
#include "ui_widget.h"
#include <QVBoxLayout>  // 引入垂直布局类的头文件,用于创建垂直方向的布局管理器
#include <QHBoxLayout>  // 引入水平布局类的头文件,用于创建水平方向的布局管理器
#include <QPushButton>  // 引入按钮类的头文件,用于创建按钮控件// 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);// 创建一个水平布局管理器对象hlayQHBoxLayout *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>  // 引入 QPushButton 类,用于创建按钮控件
#include <QGridLayout>  // 引入 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>  // 引入 QPushButton 类,用于创建按钮控件
#include <QGridLayout>  // 引入 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 列的拉伸系数为 3layout->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>  // 引入 QPushButton 类,用于创建按钮控件
#include <QLineEdit>    // 引入 QLineEdit 类,用于创建单行文本输入框控件
#include <QFormLayout>  // 引入 QFormLayout 类,用于创建表单布局管理器
#include <QLabel>       // 引入 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 <QHBoxLayout> // 引入水平布局类,用于创建水平方向的布局管理器
#include <QPushButton> // 引入按钮类,用于创建按钮控件
#include <QSpacerItem> // 引入空白间隔项类,用于在布局中添加空白间隔// 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;
}


相关文章:

  • 洛谷 P1495:【模板】中国剩余定理(CRT)/ 曹冲养猪
  • 马小帅面试遇“灵魂拷问“
  • 【前端】【面试】在 Nuxt.js SSR/SSG 应用开发的 SEO 优化方面,你采取了哪些具体措施来提高页面在搜索引擎中的排名?
  • Ubuntu22.04及以上版本buildroot SIGSTKSZ 报错问题
  • Java大厂面试:Java技术栈中的核心知识点
  • Java并发编程-多线程基础(三)
  • 集成算法学习
  • 具身系列——比较3种vpg算法方式玩CartPole游戏(强化学习)
  • 【Unity】使用XLua进行热修复
  • Ray开源程序 是用于扩展 AI 和 Python 应用程序的统一框架。Ray 由一个核心分布式运行时和一组用于简化 ML 计算的 AI 库组成
  • 4电池_基于开关电容的均衡
  • 项目实战-25年美赛MCM/ICM-基于数学建模与数据可视化的动态系统模型
  • agent初识
  • 0.1 基础阶段错题汇总
  • 前端 uni-app 初步使用指南
  • SpringMVC-第二章之RequestMapping注解详解
  • 一篇撸清 Http,SSE 与 WebSocket
  • 性能优化实践:性能监控体系
  • PyTorch_标量张量和数字的转换
  • React--》掌握react构建拖拽交互的技巧
  • 超越关税陷阱,不遗余力塑造产业的长期竞争力
  • AI世界的年轻人|与总书记交流过的“00后”,渴望紧握时代赋予的接力棒
  • 国际观察|韩国在政局多重不确定性中迎接总统选举
  • 澎湃回声丨23岁小伙“被精神病”8年续:今日将被移出“重精”管理系统
  • 大型长读长RNA测序数据集发布,有助制定精准诊疗策略
  • 朝鲜新型驱逐舰“崔贤”号进行多项武器试验