14.QT-多元素控件|QListWidget|QTableWidget|QTreeWidget(C++)

Qt中提供的多元素控件有:

  • QListWidget
  • QListView
  • QTableWidget
  • QTableView
  • QTreeWidget
  • QTreeView

以QTableWidget和QTableView为例.

  • QTableView是基于MVC设计的控件.QTableView⾃⾝不持有数据.使⽤QTableView的时候需要⽤⼾创建⼀个Model对象(⽐如 QStandardModel ),并且把Model和QTableView关联起来.后续修改Model中的数据就会影响QTableView的显⽰;修改QTableView的显⽰也会影响到Model中的数据(双向绑定).
  • QTableWidget则是QTableView的⼦类,对Model进⾏了封装.不需要⽤⼾⼿动创建Model对象,直接就可以往QTableWidget中添加数据了.
    xxView是更底层的实现
    xxWidget是基于xxView封装而来的~~ 此处xxView是MVC结构的一种典型实现
    MVC也是软件开发中,非常经典的软件结构的组织形式了.
  • M model数据
  • V view 视图 (界面)
  • C controller控制器数据和视图之间的业务流程
    此处xxView只是负责实现了视图
    不负责数据如何存储表示,更不负责数据和视图之间的交互
    因此如果使用xxView就需要程序员自己实现model 和controller的部分.就比较麻烦

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

List Widget

使⽤ QListWidget 能够显⽰⼀个纵向的列表.形如:
![[Pasted image 20250421144854.png]]

核⼼属性

属性说明
currentRow当前被选中的是第⼏⾏
count⼀共有多少⾏
sortingEnabled是否允许排序
isWrapping是否允许换⾏
itemAlignment元素的对⻬⽅式
selectRectVisible被选中的元素矩形是否可⻅
spacing元素之间的间隔
核⼼⽅法
⽅法说明
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*表⽰是哪个元素被删 除了
核⼼信号
⽅法说明
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设置⽂本对⻬⽅式.
代码⽰例:使⽤ListWidget

1)在界⾯上创建⼀个 ListView ,右键=>变形为=> ListWidget ,再创建⼀个lineEdit和两个按钮.
注意: ListWidget 是 ListView 的⼦类,功能⽐ ListView 更丰富.使⽤ListWidget 即可.
![[Pasted image 20250421151617.png]]

2)编写widget.cpp,在构造函数中添加初始元素

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

//    ui->listWidget->addItem(new QListWidgetItem("C++"));
//    ui->listWidget->addItem(new QListWidgetItem("Java"));
//    ui->listWidget->addItem(new QListWidgetItem("Python"));
}

在QListWidgetItem中,可以设置字体属性,设置图标,设置文字大小,设置是否被选中
![[Pasted image 20250421151807.png]]

或者直接点击添加项目
![[Pasted image 20250421152050.png]]

3)编写按钮的slot函数

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

![[Pasted image 20250421152634.png]]

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

![[Pasted image 20250421152902.png]]

4)编写listWidget的slot函数

  • 此处需要判定 current 和 previous ⾮空.初始情况下是没有元素选中的,就导致这俩指针可能是NULL.
void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
    //通过这个槽函数来感知到变化
    if (current != nullptr) {
        qDebug() << "当前选中的元素: " << current->text();
    }
    if (previous != nullptr) {
        qDebug() << "上次选中的元素: " << previous->text();
    }
}

这⾥需要给widget.h前⾯加上 #include <QListWidgetItem>
![[Pasted image 20250421153547.png]]

Table Widget

使⽤ QTableWidget 表⽰⼀个表格控件.⼀个表格中包含若⼲⾏,每⼀⾏⼜包含若⼲列.
表格中的每个单元格,是⼀个 QTableWidgetItem 对象.

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*)
设置指定⾏的表头

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)
选中不同单元格时触发

QTableWidgetItem 核⼼⽅法

⽅法说明
row()获取当前是第⼏⾏
column()获取当前是第⼏列
setText(const QString&)设置⽂本
setTextAlignment(int)设置⽂本对⻬
setIcon(const QIcon&)设置图标
setSelected(bool)设置被选中
setSizeHints(const QSize&)设置尺⼨
setFont(const QFont&)设置字体
代码⽰例:使⽤ QTableWidget

1)在界⾯上创建 QTableWidget 和三个按钮,⼀个输⼊框
注意: QTableWidget 是 QTableView 的⼦类,功能⽐ QTableView 更丰富.使⽤QTableWidget 即可.
![[Pasted image 20250421185206.png]]

可以在图形化界面初始化
![[Pasted image 20250421190607.png]]

2)编写widget.cpp构造函数,构造表格中的初始数据

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

![[Pasted image 20250421194938.png]]

3)编写按钮的slot函数

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

![[Pasted image 20250421200025.png]]

void Widget::on_pushButton_deleterow_clicked()
{
    //获取到要删除的选中的行号
    int curRow = ui->tableWidget->currentRow();
    //删除这一行
    ui->tableWidget->removeRow(curRow);
}
  
void Widget::on_pushButton_insertcol_clicked()
{
    //需要知道当前一共有多少列
    int colCount = ui->tableWidget->columnCount();
    //在最后一行之后新增新行
    //此处的参数是下标,表示新增之后的这一行是第几行
    ui->tableWidget->insertColumn(colCount);
    const QString& text = ui->lineEdit->text();
    ui->tableWidget->setHorizontalHeaderItem(colCount, new QTableWidgetItem(text));
}

![[Pasted image 20250421200516.png]]

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

![[Pasted image 20250421200652.png]]

默认情况下,单元格中的内容直接就是可编辑的.
如果不想让⽤⼾编辑,可以设置
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);

Tree Widget

使⽤ QTreeWidget 表⽰⼀个树形控件.⾥⾯的每个元素,都是⼀个 QTreeWidgetItem ,每个QTreeWidgetItem 可以包含多个⽂本和图标,每个⽂本/图标为⼀个列.
可以给 QTreeWidget 设置顶层节点(顶层节点可以有多个),然后再给顶层节点添加⼦节点,从⽽构成树形结构.

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)元素被展开时触发
itemCollapsend(QTreeWidgetItem*item)元素被折叠时触发

QTreeWidgetItem 核⼼属性

属性说明
text持有的⽂本
textAlignment⽂本对⻬⽅式
icon持有的图表
font⽂本字体
hidden是否隐藏
disabled是否禁⽤
expand是否展开
sizeHint尺⼨⼤⼩
selected是否选中

QTreeWidgetItem 核⼼⽅法

⽅法说明
addChild(QTreeWidgetItem*child)新增⼦节点
childCount()⼦节点的个数
child(int index)获取指定下标的⼦节点.返回QTreeWidgetItem*
takeChild(int index)删除对应下标的⼦节点
removeChild(QTreeWidgetItem*
child)
删除对应的⼦节点
parent()获取该元素的⽗节点
代码⽰例:使⽤ QTreeWidget

1)在界⾯上创建⼀个 TreeView ,右键=>变形为=> TreeWidget ,再创建⼀个lineEdit和两个按钮.
注意: TreeWidget 是 TreeView 的⼦类,功能⽐ TreeView 更丰富.使⽤ TreeWidget即可.
![[Pasted image 20250421204721.png]]

在图形界面添加元素
![[Pasted image 20250421210953.png]]

2)编写代码,构造初始数据

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

![[Pasted image 20250421211843.png]]

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

![[Pasted image 20250421213430.png]]

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

![[Pasted image 20250421213853.png]]

上述这几个控件相关的操作,数据都是在内存中保存的.无论在界面上做任何操作,重新运行程序,之前的数据就都没了
如果要想让数据能够重启也不丢失,就需要编写更多的代码吧内存存储的数据获取到,写入到文件中,并且在下次运行的时候从文件加载数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值