【QT】常⽤控件详解(六)多元素控件 QListWidget && Table Widget && Tree Widget

发布于:2025-08-13 ⋅ 阅读:(27) ⋅ 点赞:(0)

请添加图片描述


一、多元素控件

Qt 中提供的多元素控件有
列表:QListwidget,QListview
表格:QTablewidget, QTableview
树形:QTreewidget, QTreeview

xxWidgetxxView之间的区别
以QTableWidget和QTableView为例.
xxxView是底层,需要实现Model,xxxWidget是封装好的,直接添加使用

  • QTableView是基于MVC设计的控件.QTableView自身不持有数据.使用QTableView的时候需要用户创建一个Model对象(比如QstandardModel ),并且把 Model和QTableView关联起来.后续修改Model中的数据就会影响QTableView的显示;修改QTableView的显示也会影响到Model中的数据(双向绑定).
  • QTableWidget则是QTableView的子类,对Model进行了封装.不需要用户手动创建Model对象,直接就可以往QTableWidget中添加数据了.

问:什么是MVC?
MVC 是一种软件架构模式,核心是通过分离关注点提升代码可维护性、扩展性和复用性,主要包含三部分:

  • Model(模型):管理核心数据和业务逻辑,独立于视图和控制器,数据变化时会通知视图。
  • View(视图):负责数据展示,仅关注呈现形式,可多个视图对应同一模型。
  • Controller(控制器):作为中间桥梁,接收用户输入,协调模型处理数据并通知视图更新。

工作流程:用户通过视图操作→控制器接收并调用模型→模型处理后→控制器通知视图更新→呈现给用户。

二、QList Widget

2.1 核心属性与信号

  1. 核⼼属性
属性 说明
currentRow 当前被选中的是第几行
count 一共有多少行
sortingEnabled 是否允许排序
isWrapping 是否允许换行
itemAlignment 元素的对齐方式
selectRectVisible 被选中的元素矩形是否可见
spacing 元素之间的间隔
  1. 核⼼⽅法
方法 说明
addItem(const QString& label)
addItem(QListWidgetItem *item)
列表中添加元素.
currentItem() 返回 QListWidgetItem* 表示当前选中的元素
setCurrentItem(QListWidgetItem* item) 设置选中哪个元素
setCurrentRow(int row) 设置选中第几行的元素
insertItem(const QString& label, int row)
insertItem(QListWidgetItem *item, int row)
在指定的位置插入元素
item(int row) 返回 QListWidgetItem* 表示第 row 行的元素
takeItem(int row) 删除指定行的元素,返回 QListWidgetItem* 表示是哪个元素被删除了
  1. 核⼼信号
方法 说明
currentItemChanged(QListWidgetItem* current, QListWidgetItem* old) 选中不同元素时会触发.参数是当前选中的元素和之前选中的元素.
currentRowChanged(int) 选中不同元素时会触发.参数是当前选中元素的行数.
itemClicked(QListWidgetItem* item) 点击某个元素时触发
itemDoubleClicked(QListWidgetItem* item) 双击某个元素时触发
itemEntered(QListWidgetItem* item) 鼠标进入元素时触发

在上述介绍中,涉及到⼀个关键的类, QListWidgetItem这个类表⽰QListWidget中的⼀个元素.核⼼⽅法如下,本质上就是⼀个"⽂本+图标"构成的.

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

2.2 新增删除操作

创建下面控件
在这里插入图片描述
在界面上创建一个(Listview ,右键→变形为→Listwidget ,再创建一个lineEdit和两个按钮.
注意:Listwidget是(Listview的子类,功能比(Listview更丰富.咱们使用Listwidget即可.

在这里插入图片描述
代码:

#include "widget.h"
#include "ui_widget.h"
#include <QListWidgetItem>

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");
}

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

void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
    if(current != NULL && previous != NULL)
    {
        qDebug() << "当前选中:"<<current->text()
                 << "之前选中:" << previous->text();
    }
}


void Widget::on_pushButton_add_clicked()
{
    //获取到输入框的内容
    const QString& text = ui->lineEdit->text();
    if(text.isEmpty())
    {
        return;
    }
    ui->listWidget->addItem(text);
}


void Widget::on_pushButton_delete_clicked()
{
    //获取当前被选中的元素
    int row = ui->listWidget->currentRow();
    //删除这一行
    ui->listWidget->takeItem(row);
}

效果:
在这里插入图片描述

三、Table Widget

使用QTablewidget表示一个表格控件.一个表格中包含若干行,每一行又包含若干列.表格中的每个单元格,是一个QTablewidgetItem对象.

3.1 核⼼⽅法

  1. 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*) 设置指定行的表头
  1. QTableWidgetItem核⼼信号
信号 说明
cellClicked(int row, int column) 点击单元格时触发
cellDoubleClicked(int row, int column) 双击单元格时触发
cellEntered(int row, int column) 鼠标进入单元格时触发
currentCellChanged(int row, int column, int previousRow, int previousColumn) 选中不同单元格时触发
  1. QTableWidgetItem核⼼⽅法
方法 说明
row() 获取当前是第几行
column() 获取当前是第几列
setText(const QString&) 设置文本
setTextAlignment(int) 设置文本对齐
setIcon(const QIcon&) 设置图标
setSelected(bool) 设置被选中
setSizeHints(const QSize&) 设置尺寸
setFont(const QFont&) 设置字体

3.2 代码实现

创建控件,
在这里插入图片描述
然后第一种方式就直接手动编辑即可
在这里插入图片描述
在这里插入图片描述
代码实现

#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("21"));

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

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

void Widget::on_pushButton_addRow_clicked()
{
    //1,获取到行数
    int rowCount = ui->tableWidget->rowCount();
    //2,插入新行
    ui->tableWidget->insertRow(rowCount);
}


void Widget::on_pushButton_delRow_clicked()
{
    //1, 获取选中的行号
    int curRow = ui->tableWidget->currentRow();
    //2, 删除对应行
    ui->tableWidget->removeRow(curRow);
}


void Widget::on_pushButton_addCol_clicked()
{
    //1,获取到列数
    int colCount = ui->tableWidget->columnCount();
    //2,插入新行
    ui->tableWidget->insertColumn(colCount);
}


void Widget::on_pushButton_delCol_clicked()
{
    //1, 获取选中的列号
    int curCol = ui->tableWidget->currentColumn();
    //2, 删除对应的列
    ui->tableWidget->removeColumn(curCol);
}

效果:
在这里插入图片描述
默认情况下,单元格中的内容直接就是可编辑的.
如果不想让⽤⼾编辑,可以设置

ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);

四、 Tree Widget

4.1 核心方法

使用QTreewidget表示一个树形控件.里面的每个元素,都是一个QTreewidgetItem ,每个QTreewidgetItem可以包含多个文本和图标,每个文本/图标为一个列.
可以给QTreewidget设置顶层节点(顶层节点可以有多个),然后再给顶层节点添加子节点,从而构成树形结构.
在这里插入图片描述

  1. 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) 设置 TreeWidgetheader 名称.
  1. QTreeWidget核⼼信号
信号 说明
currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* old) 切换选中元素时触发
itemClicked(QTreeWidgetItem* item, int col) 点击元素时触发
itemDoubleClicked(QTreeWidgetItem* item, int col) 双击元素时触发
itemEntered(QTreeWidgetItem* item, int col) 鼠标进入时触发
itemExpanded(QTreeWidgetItem* item) 元素被展开时触发
itemCollapsend(QTreeWidgetItem* item) 元素被折叠时触发
  1. QTreeWidgetItem核⼼属性
属性 说明
text 持有的文本
textAlignment 文本对齐方式
icon 持有的图表
font 文本字体
hidden 是否隐藏
disabled 是否禁用
expand 是否展开
sizeHint 尺寸大小
selected 是否选中
  1. QTreeWidgetItem核⼼⽅法
方法 说明
addChild(QTreeWidgetItem* child) 新增子节点
childCount() 子节点的个数
child(int index) 获取指定下标的子节点.返回 QTreeWidgetItem*
takeChild(int index) 删除对应下标的子节点
removeChild(QTreeWidgetItem* child) 删除对应的子节点
parent() 获取该元素的父节点

4.2 场景实践

在这里插入图片描述

1)在界面上创建一个TreeView ,右键→变形为=→Treewidget ,再创建一个lineEdit和两个按钮.

注意:Treewidget是(Treeview的子类,功能比(Treeview更丰富.咱们使用(Treewidget即可.

构造代码:

#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);
}

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

槽函数代码

void Widget::on_pushButton_clicked()
{
    //获取输入框内容
    const QString& text = ui->lineEdit->text();
    if(text.isEmpty())
    {
        return;
    }

    //添加到顶层节点中
    QTreeWidgetItem* item = new QTreeWidgetItem();
    item->setText(0, text);
    ui->treeWidget->addTopLevelItem(item);
}


void Widget::on_pushButton_2_clicked()
{
    //获取输入框内容
    const QString& text = ui->lineEdit->text();
    if(text.isEmpty())
    {
        return;
    }

    //获取当前选中的节点
    QTreeWidgetItem* currentItem = ui->treeWidget->currentItem();
    if(currentItem == NULL)
    {
        return;
    }

    //构造新的 item
    QTreeWidgetItem* newItem = new QTreeWidgetItem();
    newItem->setText(0, text);
    //添加item 到选中节点
    currentItem->addChild(newItem);
    //展开父节点
    currentItem->setExpanded(true);
}


void Widget::on_pushButton_3_clicked()
{
    //获取到当前选中的节点
    QTreeWidgetItem* currentItem = ui->treeWidget->currentItem();
    if(currentItem == NULL)
    {
        return;
    }
    //获取当前节点的父节点
    QTreeWidgetItem* parent = currentItem->parent();
    if(parent == NULL)
    {
        //顶层节点
        int index = ui->treeWidget->indexOfTopLevelItem(currentItem);
        ui->treeWidget->takeTopLevelItem(index);
    }
    else
    {
        //非顶层节点
        parent->removeChild(currentItem);
    }
}

删除节点的逻辑

  • 如果是顶层节点(无父节点)
    if(parent == NULL) 时,通过indexOfTopLevelItem(currentItem)获取该节点在顶层节点中的索引,再用takeTopLevelItem(index)从树形控件中移除该顶层节点。

  • 如果是子节点(有父节点)
    则通过父节点的removeChild(currentItem)方法,直接从父节点中移除当前子节点。
    在这里插入图片描述


🚩总结

请添加图片描述


网站公告

今日签到

点亮在社区的每一天
去签到