【从零开始的Qt开发指南】(十一)Qt常用控件之多元素控件与容器类控件深度解析


目录

前言

一、多元素与容器类控件的核心价值

二、多元素控件:批量数据的高效展示与交互

[2.1 ListWidget:简洁高效的列表控件](#2.1 ListWidget:简洁高效的列表控件)

[2.1.1 核心属性与 API](#2.1.1 核心属性与 API)

[2.1.2 基础用法:简单列表的增删改查](#2.1.2 基础用法:简单列表的增删改查)

[2.1.3 进阶用法:带图标的列表与多选功能](#2.1.3 进阶用法:带图标的列表与多选功能)

[2.1.4 ListWidget 避坑指南](#2.1.4 ListWidget 避坑指南)

[2.2 TableWidget:功能强大的表格控件](#2.2 TableWidget:功能强大的表格控件)

[2.2.1 核心属性与 API](#2.2.1 核心属性与 API)

[2.2.2 基础用法:增删改查](#2.2.2 基础用法:增删改查)

[2.2.3 TableWidget 避坑指南](#2.2.3 TableWidget 避坑指南)

[2.3 TreeWidget:层级分明的树形控件](#2.3 TreeWidget:层级分明的树形控件)

[2.3.1 核心属性与 API](#2.3.1 核心属性与 API)

[2.3.1 基础树形结构](#2.3.1 基础树形结构)

[2.3.2 TreeWidget 避坑指南](#2.3.2 TreeWidget 避坑指南)

三、容器类控件:界面的有序组织与分组

[3.1 GroupBox:控件分组的 "收纳盒"](#3.1 GroupBox:控件分组的 “收纳盒”)

[3.1.1 核心属性与 API](#3.1.1 核心属性与 API)

[3.1.2 基础用法:表单分组](#3.1.2 基础用法:表单分组)

[3.1.3 进阶用法:扁平模式与对齐方式](#3.1.3 进阶用法:扁平模式与对齐方式)

[3.1.4 GroupBox 避坑指南](#3.1.4 GroupBox 避坑指南)

[3.2 TabWidget:多页面切换的 "导航栏"](#3.2 TabWidget:多页面切换的 “导航栏”)

[3.2.1 核心属性与 API](#3.2.1 核心属性与 API)

[3.2.2 基础用法:功能模块切换](#3.2.2 基础用法:功能模块切换)

[3.2.3 进阶用法:标签页的增加与删除](#3.2.3 进阶用法:标签页的增加与删除)

[3.2.4 TabWidget 避坑指南](#3.2.4 TabWidget 避坑指南)

总结


前言

在 Qt GUI 开发中,当需要展示批量数据或对控件进行分组管理时,单纯的基础控件已无法满足需求。多元素控件(ListWidget/TableWidget/TreeWidget)专为批量数据展示而生,支持列表、表格、树形等多样化数据呈现;容器类控件(GroupBox/TabWidget)则擅长控件分组与界面分区,让复杂界面更具逻辑性和可读性。本文基于 Qt 5.14 版本,以 "属性解析 + 实战案例 + 进阶技巧" 的结构,全面拆解这两类控件的核心用法,带你轻松搞定复杂界面开发!下面就让我们正式开始吧!


一、多元素与容器类控件的核心价值

在实际项目中,我们常面临这些场景:展示一组文件列表、呈现多行多列的表格数据、构建层级化的分类目录、将相关控件归类展示、用标签页切换不同功能模块 ------ 这正是多元素与容器类控件的用武之地。

  • 多元素控件:聚焦 "数据展示与交互",支持批量数据的添加、删除、选中、排序等操作,是处理集合数据的核心工具;
  • 容器类控件:聚焦 "界面组织与分组",通过分组、分页等方式优化界面布局,提升用户体验和界面整洁度。

本文将详细讲解 5 个核心控件:

  1. 多元素控件:ListWidget(列表)、TableWidget(表格)、TreeWidget(树形)
  2. 容器类控件:GroupBox(分组框)、TabWidget(标签页)

二、多元素控件:批量数据的高效展示与交互

多元素控件的核心优势是**"批量管理数据"**,Qt 提供了基于 Item 的简化版控件(ListWidget/TableWidget/TreeWidget),无需手动创建 Model,直接操作 Item 即可实现数据展示,开发效率极高。

2.1 ListWidget:简洁高效的列表控件

QListWidget 是垂直列表控件,适用于展示单列批量数据(如文件列表、选项列表等),支持单选、多选、添加、删除等基础操作,用法简洁直观。

2.1.1 核心属性与 API

属性 / 方法 功能说明 实用场景
currentRow() 获取当前选中行的下标(未选中返回 - 1) 选中数据后获取位置
currentItem() 获取当前选中的 Item 对象 获取选中数据的详细信息
addItem(const QString& text) 添加单个列表项 动态添加数据
addItems(const QStringList& items) 批量添加列表项 初始化批量数据
insertItem(int row, const QString& text) 在指定行插入列表项 插入中间数据
takeItem(int row) 删除指定行并返回该 Item(需手动释放) 删除数据并回收资源
setSortingEnabled(bool enable) 启用 / 禁用排序 数据排序展示
itemClicked(QListWidgetItem* item) 点击列表项时触发的信号 点击事件响应

核心数据载体:QListWidgetItem,每个 Item 可设置文本、图标、字体、选中状态等,是列表数据的最小单元。

2.1.2 基础用法:简单列表的增删改查

cpp 复制代码
#include "widget.h"
#include <QListWidget>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("ListWidget基础用法:编程语言列表");

    // 布局管理:输入框+按钮(水平布局)+列表(垂直布局)
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    QHBoxLayout *inputLayout = new QHBoxLayout();

    // 输入框:用于添加新列表项
    QLineEdit *inputEdit = new QLineEdit(this);
    inputEdit->setPlaceholderText("请输入编程语言名称");

    // 按钮:添加、删除
    QPushButton *addBtn = new QPushButton("添加", this);
    QPushButton *delBtn = new QPushButton("删除选中", this);

    // 列表控件
    QListWidget *langList = new QListWidget(this);
    // 初始化列表数据
    QStringList initLangs = {"C++", "Java", "Python", "Qt", "JavaScript", "Golang"};
    langList->addItems(initLangs);
    // 启用排序
    langList->setSortingEnabled(true);
    // 设置选中模式:单选(默认)
    langList->setSelectionMode(QAbstractItemView::SingleSelection);

    // 组装布局
    inputLayout->addWidget(inputEdit);
    inputLayout->addWidget(addBtn);
    inputLayout->addWidget(delBtn);
    mainLayout->addLayout(inputLayout);
    mainLayout->addWidget(langList);

    // 添加按钮点击事件
    connect(addBtn, &QPushButton::clicked, this, [=]() {
        QString text = inputEdit->text().trimmed();
        if (!text.isEmpty()) {
            // 添加新项并自动排序
            new QListWidgetItem(text, langList);
            inputEdit->clear();
        }
    });

    // 删除按钮点击事件
    connect(delBtn, &QPushButton::clicked, this, [=]() {
        // 获取当前选中行
        int currentRow = langList->currentRow();
        if (currentRow != -1) {
            // 删除选中项(takeItem返回Item,需手动删除避免内存泄漏)
            QListWidgetItem *item = langList->takeItem(currentRow);
            delete item;
        }
    });

    // 列表项点击事件
    connect(langList, &QListWidget::itemClicked, this, [=](QListWidgetItem *item) {
        qDebug() << "选中语言:" << item->text();
    });
}

2.1.3 进阶用法:带图标的列表与多选功能

ListWidget 支持为 Item 添加图标,且支持多选模式,适用于文件列表、应用列表等场景:

先在.ui文件中创建控件:

编写代码:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //往这里添加一些元素
    ui->listWidget->addItem("C++");
    ui->listWidget->addItem("Java");
    ui->listWidget->addItem("Python");

    //在QListWidgetItem中,可以设置字体属性,设置图标,设置文字大小,设置是否被选中等状态
//    ui->listWidget->addItem(new QListWidgetItem("C++"));
//    ui->listWidget->addItem(new QListWidgetItem("Java"));
//    ui->listWidget->addItem(new QListWidgetItem("Python"));
    //也可以在.ui文件中通过图形化界面编辑
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_insert_clicked()
{
    //1.先获取到输入框中的内容
    const QString& text =ui->lineEdit->text();
    //2.添加到QListWidget中
    ui->listWidget->addItem(text);  //添加到末尾,如果想添加到中间位置,需要使用insertItem
}

void Widget::on_pushButton_delete_clicked()
{
    //1.先获取到被选中的元素
    int row = ui->listWidget->currentRow();
    if(row < 0)
    {
        return;
    }
    //2.按照行号来删除元素
    ui->listWidget->takeItem(row);
}

void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
    //通过这个槽函数来感知到变化
    if(current != nullptr)
    {
        qDebug() << "当前选中的元素:" << current->text();
    }
    if(previous != nullptr)
    {
        qDebug() << "上次选中的元素:" << previous->text();
    }
}

运行结果如下:

2.1.4 ListWidget 避坑指南

  1. 内存泄漏takeItem方法会从列表中移除 Item 但不删除,需手动delete回收资源;
  2. 排序不生效 :需先调用setSortingEnabled(true),新增 Item 才会自动排序;
  3. 多选获取 :通过selectedItems()获取所有选中项,返回QList<QListWidgetItem*>
  4. Item 编辑 :需设置item->setFlags(item->flags() | Qt::ItemIsEditable),默认不可编辑。

2.2 TableWidget:功能强大的表格控件

QTableWidget 是多行多列的表格控件,适用于展示结构化数据(如学生信息表、商品列表、数据统计等),支持单元格编辑、表头自定义、行高列宽调整等功能,是 Qt 中最常用的多元素控件之一。

2.2.1 核心属性与 API

属性 / 方法 功能说明 实用场景
setColumnCount(int count) 设置列数 初始化表格结构
setRowCount(int count) 设置行数 初始化表格结构
setHorizontalHeaderItem(int col, QTableWidgetItem* item) 设置列标题 自定义表头文本 / 样式
setItem(int row, int col, QTableWidgetItem* item) 设置单元格内容 填充表格数据
currentRow()/currentColumn() 获取当前选中单元格的行 / 列下标 定位选中位置
insertRow(int row)/insertColumn(int col) 插入行 / 列 动态添加数据
removeRow(int row)/removeColumn(int col) 删除行 / 列 动态删除数据
setEditTriggers(QAbstractItemView::EditTriggers triggers) 设置编辑触发方式 控制单元格是否可编辑
horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode mode) 设置列宽调整模式 自适应列宽 / 固定列宽

核心数据载体:QTableWidgetItem,每个单元格对应一个 Item,支持设置文本、图标、对齐方式、字体等。

2.2.2 基础用法:增删改查

在.ui文件中创建控件:

编写代码:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //创建三行
    ui->tableWidget->insertRow(0);
    ui->tableWidget->insertRow(1);
    ui->tableWidget->insertRow(2);

    //创建三列
    ui->tableWidget->insertColumn(0);
    ui->tableWidget->insertColumn(1);
    ui->tableWidget->insertColumn(2);

    //给三列设置列名(设置水平方向的表头)
    ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("学号"));
    ui->tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem("姓名"));
    ui->tableWidget->setHorizontalHeaderItem(2, new QTableWidgetItem("年龄"));

    //给表格中添加数据
    ui->tableWidget->setItem(0, 0, new QTableWidgetItem("1001"));
    ui->tableWidget->setItem(0, 1, new QTableWidgetItem("张三"));
    ui->tableWidget->setItem(0, 2, new QTableWidgetItem("20"));

    ui->tableWidget->setItem(1, 0, new QTableWidgetItem("1002"));
    ui->tableWidget->setItem(1, 1, new QTableWidgetItem("李四"));
    ui->tableWidget->setItem(1, 2, new QTableWidgetItem("19"));

    ui->tableWidget->setItem(2, 0, new QTableWidgetItem("1003"));
    ui->tableWidget->setItem(2, 1, new QTableWidgetItem("王五"));
    ui->tableWidget->setItem(2, 2, new QTableWidgetItem("18"));
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_insertRow_clicked()
{
    //需要知道当前一共有多少行
    int rowCount = ui->tableWidget->rowCount();
    //在最后一行之后新增新行
    //注意此处的参数是"下标",表示你新增之后的一行是第几行
    ui->tableWidget->insertRow(rowCount);
}

void Widget::on_pushButton_deleteRow_clicked()
{
    //获取到选中的行号
    int curRow = ui->tableWidget->currentRow();
    //删除这一行
    ui->tableWidget->removeRow(curRow);
}

void Widget::on_pushButton_insertColumn_clicked()
{
    //需要知道当前一共有多少列
    int colCount = ui->tableWidget->columnCount();
    //在对应位置新增新列
    ui->tableWidget->insertColumn(colCount);
    //设置列名(从输入框中获取到)
    const QString& text = ui->lineEdit->text();
    ui->tableWidget->setHorizontalHeaderItem(colCount, new QTableWidgetItem(text));
}

void Widget::on_pushButton_4_clicked()
{
    //获取到选中的列号
    int curCol = ui->tableWidget->currentColumn();
    //删除这一列
    ui->tableWidget->removeColumn(curCol);
}

运行结果:

2.2.3 TableWidget 避坑指南

  1. 表头设置setHorizontalHeaderLabels需在setColumnCount之后调用,否则表头不生效;
  2. 单元格居中 :默认单元格文本左对齐,需手动设置item->setTextAlignment(Qt::AlignCenter);
  3. 行高列宽QHeaderView::Stretch表示自适应拉伸,QHeaderView::Fixed表示固定尺寸;
  4. 编辑控制 :**setEditTriggers(QAbstractItemView::NoEditTriggers)**可禁用单元格编辑,避免误操作;
  5. 数据获取 :通过**item(row, col)**获取单元格数据,需判断 Item 是否为nullptr(避免空指针崩溃)。

2.3 TreeWidget:层级分明的树形控件

QTreeWidget 是树形结构控件,适用于展示层级化数据(如文件目录、分类菜单、组织架构等),支持父节点、子节点的嵌套展示,支持展开 / 折叠操作。

2.3.1 核心属性与 API

属性 / 方法 功能说明 实用场景
setHeaderLabel(const QString& text) 设置表头文本(单列) 单列树形结构
setColumnCount(int count) 设置列数(多列树形) 多列树形结构(如文件名称 + 大小)
addTopLevelItem(QTreeWidgetItem* item) 添加顶层节点 初始化根节点
QTreeWidgetItem* topLevelItem(int index) 获取指定顶层节点 操作顶层节点
topLevelItemCount() 获取顶层节点个数 遍历顶层节点
item->addChild(QTreeWidgetItem* child) 为节点添加子节点 构建层级结构
item->setExpanded(bool expanded) 设置节点是否展开 默认展开 / 折叠节点
currentItem() 获取当前选中的节点 操作选中节点
itemExpanded(QTreeWidgetItem* item) 节点展开时触发的信号 展开节点时加载子数据

核心数据载体:QTreeWidgetItem,每个节点对应一个 Item,支持多列数据,可通过**setText(col, text)**设置每列内容。

2.3.1 基础树形结构

先创建控件:

编写代码:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //设置根节点的名字
    ui->treeWidget->setHeaderLabel("动物");

    //新增顶层结点
    QTreeWidgetItem* item1 = new QTreeWidgetItem();
    //每个结点都可以设置多个列,此处为了简单就只设置一列
    item1->setText(0, "猫");
    //添加到顶层结点中
    ui->treeWidget->addTopLevelItem(item1);

    //新增顶层结点
    QTreeWidgetItem* item2 = new QTreeWidgetItem();
    //每个结点都可以设置多个列,此处为了简单就只设置一列
    item2->setText(0, "狗");
    //添加到顶层结点中
    ui->treeWidget->addTopLevelItem(item2);

    //新增顶层结点
    QTreeWidgetItem* item3 = new QTreeWidgetItem();
    //每个结点都可以设置多个列,此处为了简单就只设置一列
    item3->setText(0, "鸟");
    //添加到顶层结点中
    ui->treeWidget->addTopLevelItem(item3);

    //新增一些子结点
    QTreeWidgetItem* item4 = new QTreeWidgetItem();
    item4->setText(0, "中华田园猫");
    item1->addChild(item4);

    QTreeWidgetItem* item5 = new QTreeWidgetItem();
    item5->setText(0, "布偶猫");
    item1->addChild(item5);

    QTreeWidgetItem* item6 = new QTreeWidgetItem();
    item6->setText(0, "暹罗猫");
    item1->addChild(item6);
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_insertTopLevelItem_clicked()
{
    //获取到输入框中的内容
    const QString& text = ui->lineEdit->text();
    //构造一个QTreeWidgetItem
    QTreeWidgetItem* item = new QTreeWidgetItem();
    item->setText(0, text);
    //添加到顶层结点中
    ui->treeWidget->addTopLevelItem(item);
}

void Widget::on_pushButton_insertItem_clicked()
{
    //获取到当前选中的结点
    QTreeWidgetItem* currentItem = ui->treeWidget->currentItem();
    if(currentItem == nullptr)
    {
        return;
    }
    //获取到输入框中的内容
    const QString& text = ui->lineEdit->text();
    //构造一个QTreeWidgetItem
    QTreeWidgetItem* item = new QTreeWidgetItem();
    item->setText(0, text);
    //插入到选中结点的子结点中
    currentItem->addChild(item);
}

void Widget::on_pushButton_deleteItem_clicked()
{
    //获取到当前选中的结点
    QTreeWidgetItem* currentItem = ui->treeWidget->currentItem();
    if(currentItem == nullptr)
    {
        return;
    }
    //删除选中的元素,需要先获取到父元素,通过父元素进行删除
    QTreeWidgetItem* parent = currentItem->parent();
    if(parent == nullptr)
    {
        //顶层元素
        int index = ui->treeWidget->indexOfTopLevelItem(currentItem);
        ui->treeWidget->takeTopLevelItem(index);
    }
    else
    {
        //普通元素
        parent->removeChild(currentItem);
    }
}

运行结果:

2.3.2 TreeWidget 避坑指南

  1. 节点层级 :顶层节点通过addTopLevelItem添加,子节点通过parentItem->addChild添加;
  2. 路径获取 :通过递归遍历**parent()**可获取节点的完整路径;
  3. 节点删除 :子节点需通过父节点removeChild删除,顶层节点需通过树形控件takeTopLevelItem删除;
  4. 多列设置setColumnCount需在设置表头前调用,**setText(col, text)**设置对应列内容;
  5. 图标设置 :**setIcon(col, icon)**设置对应列的图标,默认列索引为 0。

三、容器类控件:界面的有序组织与分组

容器类控件本身不直接展示数据,而是作为 "容器" 管理其他控件,通过分组、分页等方式优化界面结构,让复杂界面更易理解和操作。

3.1 GroupBox:控件分组的 "收纳盒"

QGroupBox 是带标题的分组框,适用于将相关控件归类展示(如表单中的同一模块、选项组等),支持边框显示、标题自定义,还可设置为可勾选模式(勾选后才启用组内控件)。

3.1.1 核心属性与 API

属性 / 方法 功能说明 实用场景
setTitle(const QString& title) 设置分组框标题 标识分组用途
setFlat(bool flat) 设置是否为扁平模式(无边框) 简洁界面风格
setCheckable(bool checkable) 设置是否可勾选 控制组内控件启用 / 禁用
setChecked(bool checked) 设置勾选状态 默认启用 / 禁用组内控件
setAlignment(Qt::Alignment alignment) 设置组内控件对齐方式 优化组内布局

3.1.2 基础用法:表单分组

先创建控件:

运行结果如下:

3.1.3 进阶用法:扁平模式与对齐方式

cpp 复制代码
#include "widget.h"
#include <QGroupBox>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("GroupBox进阶:扁平模式与对齐");

    QVBoxLayout *mainLayout = new QVBoxLayout(this);

    // 扁平模式分组框(无边框)
    QGroupBox *flatGroup = new QGroupBox("操作按钮", this);
    flatGroup->setFlat(true); // 扁平模式
    QHBoxLayout *flatLayout = new QHBoxLayout(flatGroup);

    flatLayout->addWidget(new QPushButton("新建", this));
    flatLayout->addWidget(new QPushButton("打开", this));
    flatLayout->addWidget(new QPushButton("保存", this));
    flatLayout->addWidget(new QPushButton("删除", this));

    // 右对齐分组框
    QGroupBox *alignGroup = new QGroupBox("选项设置", this);
    alignGroup->setAlignment(Qt::AlignRight); // 组内控件右对齐
    QVBoxLayout *alignLayout = new QVBoxLayout(alignGroup);

    alignLayout->addWidget(new QCheckBox("启用自动保存", this));
    alignLayout->addWidget(new QCheckBox("显示状态栏", this));
    alignLayout->addWidget(new QCheckBox("允许拖拽", this));

    mainLayout->addWidget(flatGroup);
    mainLayout->addWidget(alignGroup);
}

3.1.4 GroupBox 避坑指南

  1. 组内布局:GroupBox 必须设置布局管理器(如 QVBoxLayout),否则内部控件无法正常显示;
  2. 勾选功能 :**setCheckable(true)**后,组内控件默认随勾选状态启用 / 禁用,无需手动控制;
  3. 扁平模式 :**setFlat(true)**会隐藏边框,仅显示标题,适用于简洁界面;
  4. 对齐方式setAlignment控制组内控件的整体对齐,而非标题对齐。

3.2 TabWidget:多页面切换的 "导航栏"

QTabWidget 是标签页控件,适用于将不同功能模块放在不同标签页中(如设置界面、编辑界面等),通过切换标签页实现功能切换,节省界面空间,提升界面整洁度。

3.2.1 核心属性与 API

属性 / 方法 功能说明 实用场景
addTab(QWidget* page, const QString& label) 添加标签页(页面 + 标题) 新增功能模块
insertTab(int index, QWidget* page, const QString& label) 在指定位置插入标签页 调整标签页顺序
removeTab(int index) 删除指定标签页 动态移除模块
currentIndex() 获取当前选中标签页的下标 判断当前激活模块
setCurrentIndex(int index) 设置当前选中标签页 手动切换模块
setTabText(int index, const QString& text) 修改标签页标题 动态更新标题
setTabIcon(int index, const QIcon& icon) 设置标签页图标 美化标签页
setTabsCloseable(bool closeable) 设置标签页是否可关闭 支持动态关闭标签页
currentChanged(int index) 标签页切换时触发的信号 切换模块时执行初始化

3.2.2 基础用法:功能模块切换

先创建控件:

运行结果如下:

3.2.3 进阶用法:标签页的增加与删除

编辑.ui文件:

编写代码:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QLabel>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //先在每个标签页中,添加一个Label
    QLabel* label1 = new QLabel(ui->tab);
    label1->setText("标签页1");
    label1->resize(100, 50);

    QLabel* label2 = new QLabel(ui->tab_2);
    label2->setText("标签页2");
    label2->resize(100, 50);
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_clicked()
{
    //使用addTab方法创建新的标签页
    //参数1 要指定一个QWidget
    //参数2 指定这个标签页的text(标题),此处标题就叫做Tab + 数字
    int count = ui->tabWidget->count(); //获取到标签页的数量
    QWidget* w = new QWidget();
    ui->tabWidget->addTab(w, QString("Tab ") + QString::number(count + 1));
    //添加一个QLabel显示内容
    QLabel* label = new QLabel(w);
    label->setText(QString("标签页") +QString::number(count + 1));
    label->resize(100, 50);
    //设置新标签页被选中
    ui->tabWidget->setCurrentIndex(count);
}

void Widget::on_pushButton_2_clicked()
{
    //获取到当前选中的标签页的下标
    int index = ui->tabWidget->currentIndex();
    //删除标签页
    ui->tabWidget->removeTab(index);
}

void Widget::on_tabWidget_currentChanged(int index)
{
    qDebug() << "当前选中的标签页是:" << index;
}

运行结果如下:

3.2.4 TabWidget 避坑指南

  1. 页面创建:每个标签页必须是独立的 QWidget,且需设置布局管理器,否则控件无法正常排列;
  2. 关闭标签页setTabsCloseable(true)后,通过tabCloseRequested信号处理关闭逻辑,需手动调用removeTab
  3. 动态标题 :通过setTabText可动态更新标签页标题,适用于显示实时状态;
  4. 嵌套布局:标签页内部可嵌套任意布局,支持复杂界面设计;
  5. 切换初始化currentChanged信号在标签页切换时触发,可用于初始化当前页面数据。

总结

多元素与容器类控件是 Qt 界面开发的核心工具,掌握它们的使用后,可轻松应对复杂数据展示和界面布局需求。如果本文对你有帮助,欢迎点赞、收藏、转发,如有疑问或建议,欢迎在评论区留言交流~

相关推荐
用户805533698033 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner3 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz8 天前
QML Hello World 入门示例
qt
xcyxiner11 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner11 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner12 天前
DicomViewer (添加模型类)3
qt
xcyxiner13 天前
DicomViewer (目录调整) 2
qt
xcyxiner13 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00614 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术14 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript