【Qt】Qt多元素控件深入解析与实战应用:列表(QListWidget)、表格(QTableWidget)与树形(QTreeWidget)结构

前言:

在Qt框架中,用户界面的构建是一个至关重要的环节,而其中多元素控件的使用更是构建丰富用户界面的核心。本文将深入探讨Qt中的三种主要多元素控件:List Widget、Table Widget和Tree Widget。通过详细的代码示例和功能解析,本文旨在帮助开发者更好地理解和运用这些控件,以创建具有交互性和功能性的应用程序界面。无论是初学者还是有经验的开发者,都能从本文中获得有价值的信息和启发。

Qt中多元素控件:

Qt 中多元素控件有:
列表QListWidget + QListView
表格: QTableWidget + QTableView
树形QTreeWidget + QTreeView

  • xxWidget 与 xxView 是啥区别?
    xxView 是更底层的实现。
    xxWidget 是 基于 xxView 封装而来的。

此处xxView 是 MVC 结构的一种典型实现 MVC 也是软件开发中,非常经典的 软件结构的组织形式了

M:model 数据
V:view 视图(界面)
C:controller 控制器,数据和是同之间的业务流程

  • xxView 只是负责实现了视图,不负责数据如何存储表述,更不负责数据是同之间的交互。因此,如果使用xxView就需要程序员自己实现 model 和 controller 的部分,就比较麻烦。

  • xxWidget 基于 xxView 同时把 model 和 control 都帮我们实现好了,拿过来就可以使用,人家提供了功能很方便的api,让我们直接就用。

  • xxWidget 使用起来比较方便,但是功能会比较的有限。

  • xxView 使用起来更麻烦一些,但可以根据情况自由 DIY ,实现一些更复杂的功能。

1. List Widget

使用 QListWidget 都能显示一个纵向的列表,形如:
在这里插入图片描述
列表中的每一个元素/每一项就称为一个 Item
更具体的说,通过 QListWidgetItem 类表示的!

在这里插入图片描述
在这里插入图片描述

此处的row参数就表示插入完毕之后的元素在第几行,把新元素插入到第几行之前。

takeItem:take 也是用来表示 “删除” 术语 (erase、remove、delete、take)

在这里插入图片描述

1.1. 代码示例: 使用 ListWidget

先往这里添加一些元素

  • 添加方式 1:
ui->listWidget->addItem("C++");
ui->listWidget->addItem("Java");
ui->listWidget->addItem("Python");
  • 添加方式 2:
ui->listWidget->addItem(new QListWidgetItem("C++"));
ui->listWidget->addItem(new QListWidgetItem("Java"));
ui->listWidget->addItem(new QListWidgetItem("Python"));

QListWidgetItem 中, 可以设置字体属性,设置图标,设置文字大小, 设置是否被选中等状态。

  • 添加方式 3 : 通过图形化界面进行添加
    在这里插入图片描述
    通过图形化界面,右键 QListWidget,选择编辑项目就可以之间添加内容。
  • 如果这里初始化内容是固定的,此时你通过那种方式来初始化都可以。
  • 如果这里的内容不是固定的,就要通过 读取文件/读取网络 来构造数据,就需要通过代码的方式来添加了。
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

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

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

//    // 添加方式 2
//    ui->listWidget->addItem(new QListWidgetItem("C++"));
//    ui->listWidget->addItem(new QListWidgetItem("Java"));
//    ui->listWidget->addItem(new QListWidgetItem("Python"));

    // 添加方式 3 : 通过图形化界面进行添加
}

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


void Widget::on_pushButton_insert_clicked()
{
    // 1. 先获取到输入框中的内容
    const QString& text = ui->lineEdit->text();
    // 2. 添加到 QListWidget 中
    ui->listWidget->addItem(text);
}

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.Table Widget

使用 QTableWidget 表示一个表格控件,一个表格中包含若干行,每一行又包含若干列。
表格中的每一个单元,是一个 QTableWidgetItem 对象。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.1. 代码示例: 使用 QTableWidget

在这里插入图片描述

如果当前表格中的数据是固定的,完全可以通过图形化的方式来进行编辑,但实际开发中,很多时候数据是从 文件/网络 加载过来的, 此时通过图形化编辑就不合适了。

  • 通过代码编写:
#include "widget.h"
#include "ui_widget.h"

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

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

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

    // 给 3 个列设定列名(设施水平方向的表头)
    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("21"));
}

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


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

void Widget::on_pushButton_deleteLine_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_Column_clicked()
{
    // 获取到选中的列号
    int curCol = ui->tableWidget->currentColumn();
    // 删除这一列
    ui->tableWidget->removeColumn(curCol);
}

在这里插入图片描述

3. Tree Widget

使用 QTreeWidget 表示一个树形控件。里面的每个元素,都是一个 QTreeWidgetItem,每个QTreeWidgetItem 可以包含多个文本和图标,每个文本/图标为一个列。
可以给 QTreeWidget 设置顶层节点(顶层节点可以有多个), 然后再给顶层节点添加子节点, 从而构成树形结构。
在这里插入图片描述
QTreeWidget 控件虽然是树形结构,但是这个树形结构,没有体现出根节点,是从根节点的下一层子节点开始计算的。
在这里插入图片描述
针对顶层节点来说,这里也是一个类似于 “List” 这样的结构 !
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.1. 代码示例: 使用 QTreeWidget

#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_insertTopLeveItem_clicked()
{
    // 获取到输入框中的内容
    const QString& text = ui->lineEdit->text();
    // 判断输入框是否为空
    if (text.isEmpty()) {
        return;
    }
    // 构造一个 QTreeWidetITem
    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();
    // 判断输入框是否为空
    if (text.isEmpty()) {
        return;
    }
    // 构造一个 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);
    }
}

在这里插入图片描述

总结:

本文详细介绍了Qt中的三种多元素控件:List Widget、Table Widget和Tree Widget,它们分别用于展示列表、表格和树形结构的数据。通过代码示例,我们展示了如何使用这些控件进行数据的添加、删除和修改操作。同时,也解释了xxWidget与xxView之间的区别,以及它们在MVC架构中扮演的角色。xxWidget提供了封装好的模型和控制器,使得开发者可以快速地实现功能,而xxView则提供了更底层的视图实现,允许开发者有更大的灵活性来自定义功能。

然而,需要注意的是,这些控件默认情况下只将数据保存在内存中,一旦程序重启,之前的数据就会丢失。为了实现数据的持久化,开发者需要编写额外的代码,将数据写入文件,并在程序启动时从文件中加载数据。通过本文的学习,开发者应该能够更加熟练地使用Qt中的多元素控件,并理解如何通过编程实现数据的持久化存储。

  • 40
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Q_hd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值