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

文章目录

  • 一、多元素控件
  • [二、QList Widget](#二、QList Widget)
    • [2.1 核心属性与信号](#2.1 核心属性与信号)
    • [2.2 新增删除操作](#2.2 新增删除操作)
  • [三、Table Widget](#三、Table Widget)
    • [3.1 核⼼⽅法](#3.1 核⼼⽅法)
    • [3.2 代码实现](#3.2 代码实现)
  • [四、 Tree Widget](#四、 Tree Widget)
    • [4.1 核心方法](#4.1 核心方法)
    • [4.2 场景实践](#4.2 场景实践)
  • 🚩总结

一、多元素控件

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即可.

代码:

coffeescript 复制代码
#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 代码实现

创建控件,

然后第一种方式就直接手动编辑即可

代码实现

coffeescript 复制代码
#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);
}

效果:

默认情况下,单元格中的内容直接就是可编辑的.

如果不想让⽤⼾编辑,可以设置

coffeescript 复制代码
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即可.

构造代码:

coffeescript 复制代码
#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;
}

槽函数代码

coffeescript 复制代码
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)方法,直接从父节点中移除当前子节点。


🚩总结

相关推荐
GetcharZp18 分钟前
C++ Boost 从入门到精通:让你的代码飞起来
c++·后端
带只拖鞋去流浪21 分钟前
Java文件读写(IO、NIO)
java·开发语言·nio
mit6.8241 小时前
[LVGL] 配置lv_conf.h | 条件编译 | 显示屏lv_display
c++·mfc
板鸭〈小号〉1 小时前
线程安全的单例模式,STL和智能指针
开发语言·c++·单例模式
小伟的技术日记1 小时前
MATLAB下载教程MATLAB R2025a 保姆级安装步骤(附安装包)
开发语言·其他·数学建模·matlab
阿狗哲哲1 小时前
Java选手如何看待Golang
java·开发语言·golang
阿飞__2 小时前
C++使用FFmpeg进行视频推流
c++·ffmpeg·音视频
limitless_peter2 小时前
优先队列,链表优化
c++·算法·链表
测试开发技术2 小时前
软件测试中,pytest 运行完成后,如何自动发送邮件?
开发语言·python·pytest·接口测试·面试题
曹牧2 小时前
C#:dnSpy
开发语言·c#