目录
1.多元素控件介绍
2.ListWidget控件
属性
核心方法
核心信号
细节
Demo:编辑日程
3.TableWidget控件
核心方法
QTableWidgetItem核心信号
QTableWidgetItem核心方法
细节
Demo:编辑学生信息
4.TreeWidget控件
核心方法
核心信号
QTreeWidgetItem核心方法
细节
控件使用案例
1.多元素控件介绍
Qt中为我们提供的多元素控件有QListWidget、QListView、QTableWidget、QTableView、QTreeWidget、QTreeView六个。那么我可以发现,他们是两两一组,xxxWidget和xxxView两种形式,那么他俩之间有什么区别呢?
xxxView是更底层的实现,xxxWidget是基于xxxView封装而来的,用户使用起来比较容易。此处的xxxView是MVC结构的实现,MVC是软件开发中非常经典的软件结构组织形式。
M:model数据 V:view视图(界面) C:controller控制器,数据和视图之间的业务流程。
对于xxxView来说只是负责了上述的视图,不负责数据如何表示,以及数据和视图之间如何交互,如果用户使用xxxView的话,就需要自己创建model对象,和视图关联起来。而QxxxWidget则是QxxxView的子类,对Model进行了封装,不需要我们自己去创建model对象,直接向xxxWidget中添加数据即可。
2.ListWidget控件
该控件表示的是一个纵向的列表
属性
| 属性 | 说明 | 
| currentRow | 当前被选中的是第几行 | 
| count | 一共有多少行 | 
| sortingEnabled | 是否允许排序 | 
| isWrapping | 是否允许换行 | 
| itemAlignment | 元素的对齐方式 | 
| selectRectVisible | 被选中的元素矩形是否可见 | 
| spacing | 元素之间的间隔 | 
核心方法
| 方法 | 说明 | 
| addItem(QString& label) addItem(QListWidgetItem* item) | 列表中添加元素 | 
| currentItem() | 返回当前选中的QListWidgetItem* 对象元素 | 
| setCurrentItem(QListWidgetItem* item) | 设置选中哪一个元素 | 
| setCurrentRow(int row) | 设置选中第几行的元素 | 
| insertItem(const QString& label, int row) insertItem(QListWidgetItem* item, int row) | 第一个是添加到最后一行,这个方法是插入到第row行 | 
| item(int row) | 获取第row行的QListWidgetItem* 对象元素 | 
| takeItem(int row) | 删除指定行的元素,返回删除的元素对象 | 
核心信号
| 信号 | 说明 | 
| currentItemChanged(QListWidgetItem* current, QListWidgetItem* old) | 选中不同元素的时候会触发,参数是当前选中的元素和之前选中的元素 | 
| currentRowChanged(int) | 选中不同元素的时候触发,参数是当前选中元素的行数 | 
| itemClicked(QListWidgetItem* item) | 点击某个元素的时候触发 | 
| itemDoubleClicked(QListWidgetItem* item) | 双击某个元素的时候触发 | 
| itemEntered(QListWidgetItem* item) | 鼠标进入元素范围触发 | 
细节
- 对于一个QListWidget控件,内部的元素是一个个的QListWidgetItem组成的。本质上改类的内部就是一个文本+图标构成,所以QListWidgetItem内部提供了很多操作文本和图标的方法。例如:设置字体、设置图标、设置对齐方式等内容。
Demo:编辑日程
该demo中有QListWidget控件来显示日程列表,提供了两个按钮去进行操作日程表的添加和删除的操作,为添加按钮设置一个QLineEdit控件,在增加的时候,获取QLineEdit控件输入的内容,然后添加到日程表当中。删除的时候,获取到选中的是第几行,然后进行调用方法删除。
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //初始化日程表
    //以字符串形式添加元素
    ui->listWidget->addItem("健身");
    ui->listWidget->addItem("学习");
    ui->listWidget->addItem("打球");
    //用对象的形式添加元素
    QListWidgetItem* item = new QListWidgetItem("玩游戏");
    ui->listWidget->addItem(item);
    //匿名对象添加元素
    ui->listWidget->addItem(new QListWidgetItem("吃饭"));
}
Widget::~Widget()
{
    delete ui;
}
//增加日程
void Widget::on_pushButton_add_clicked()
{
    //获取lineEdit单行输入框中的内容
    const QString str = ui->lineEdit->text();
    //设置到listWidegt控件中
    ui->listWidget->addItem(new QListWidgetItem(str));
}
//删除日程
void Widget::on_pushButton_del_clicked()
{
    //获取到被选中的元素的行号
    int row = ui->listWidget->currentRow();
    if(row < 0)
        return;
    //删除
    ui->listWidget->takeItem(row);
}
3.TableWidget控件
该控件表示的是一个表格控件,包括横向和纵向两个方向由若干行若干列组成,每一个表格都是由一个QTableWidgetItem对象构成。
核心方法
| 方法 | 说明 | 
| item(int row, int column) | 根据行数和列数获取指定的QTableWidgetItem*对象 | 
| setItem(int row, int column, QTbleWidget*) | 根据行数列数设置表格中的元素 | 
| 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*) | 设置指定列的表头 | 
| setVericalHeaderItem(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 prevuiousRow, int previousColumn) | 选中不同的单元格的时候触发 | 
QTableWidgetItem核心方法
| 方法 | 说明 | 
| row() | 获取当前在第几行 | 
| column() | 获取当前在第几列 | 
| setText(const QString&) | 设置文本 | 
| setTextAlignment(int) | 设置文本呢对齐方式 | 
| setlcon(const QIcon&) | 设置图标 | 
| setSelected(bool) | 设置被选中 | 
| setSizeHints(const QSize&) | 设置尺寸 | 
| setFont(onst QFont&) | 设置字体 | 
细节
- 对于单元格默认程序运行之后是可以编写文本内容的,如果我们不想让用户去修改单元格中的内容的话,需要设置:
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
Demo:编辑学生信息
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->lineEdit->setPlaceholderText("请输入新增的列名称");
    //创建3行3列
    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("2000"));
    ui->tableWidget->setItem(0, 1, new QTableWidgetItem("zhangsan"));
    ui->tableWidget->setItem(0, 2, new QTableWidgetItem("000-0000-0000"));
    ui->tableWidget->setItem(1, 0, new QTableWidgetItem("2001"));
    ui->tableWidget->setItem(1, 1, new QTableWidgetItem("lisi"));
    ui->tableWidget->setItem(1, 2, new QTableWidgetItem("123-4567-8901"));
    ui->tableWidget->setItem(2, 0, new QTableWidgetItem("2002"));
    ui->tableWidget->setItem(2, 1, new QTableWidgetItem("wangwu"));
    ui->tableWidget->setItem(2, 2, new QTableWidgetItem("342-4483-1992"));
}
Widget::~Widget()
{
    delete ui;
}
//增加一行
void Widget::on_pushButton_add_row_clicked()
{
    //获取行数
    int row_count = ui->tableWidget->rowCount();
    //增加一行
    ui->tableWidget->insertRow(row_count);
}
//增加一列
void Widget::on_pushButton_column_add_clicked()
{
    //获取列数
    int column_count = ui->tableWidget->columnCount();
    //获取新增列的表头
    const QString str = ui->lineEdit->text();
    //如果为空的话,就不添加了
    if(str.isEmpty())
        return;
    //增加一列
    ui->tableWidget->insertColumn(column_count);
    //设置表头
    ui->tableWidget->setHorizontalHeaderItem(column_count, new QTableWidgetItem(str));
}
//删除选中行
void Widget::on_pushButton_row_del_clicked()
{
    //获取当前选中的行
    int row = ui->tableWidget->currentRow();
    //删除
    ui->tableWidget->removeRow(row);
}
//删除选中列
void Widget::on_pushButton_column_del_clicked()
{
    //获取当前选中的列
    int column = ui->tableWidget->currentColumn();
    //删除
    ui->tableWidget->removeColumn(column);
}

4.TreeWidget控件
该控件表示的是一个树形的控件,里面的每一元素都是一个QTreeWidgetItem对象,该对象内部可以包含多个文本和图标,每一个文本或者图标是一列。可以给QTreeWidget设置顶层节点,顶层节点可以是多个,然后再给顶层节点添加子节点,从而构成了树形结构。
核心方法
| 方法 | 说明 | 
| clear() | 清空所有子节点 | 
| addTopLevelItem(QTreeWidegtItem* 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名称 | 
核心信号
| 信号 | 说明 | 
| currentChanged(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核心方法
| 方法 | 说明 | 
| addChild(QTreeWidgetItem* child) | 新增子节点 | 
| childCount() | 获取子节点个数 | 
| child(int index) | 获取指定下标的子节点,返回QTreeWidgetItem对象指针 | 
| takeChild(int index) | 删除指定下标的子节点 | 
| removeChild(QTreeWidgetItem* child) | 删除对应的元素 | 
| parent() | 获取该元素的父节点 | 
细节
- 在添加顶层节点或者子节点传递QTreeWidgetItem对象的时候,在设置文本的时候,需要传递两个参数,第一个表示第n列,第二个参数是文本内容,因为QTreeWidgetItem对象可以有很多列,所以需要传递设置的文本是第几列。但是如果设置多列的话,那么我们对应的设置控件名称的时候就需要调用setHeaderLabels设置多个列名称了。这样的话才能显示出来我们设置的多列元素。
- 对于删除的时候来说,删除的时候需要调用他的父节点的删除函数,所以说要考虑删除元素的是不是顶层元素,因为顶层元素没有父元素,所以需要调用控件的删除函数去删除顶层元素,如果不是的话,调用父节点的删除函数即可。
- 如果删除的节点下面还有子节点的话,也会一起删除的。
控件使用案例
#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);
}
Widget::~Widget()
{
    delete ui;
}
//添加顶层元素
void Widget::on_pushButton_topItem_add_clicked()
{
    //获取输入框的文本内容
    const QString& str = ui->lineEdit->text();
    if(str.isEmpty())
        return;
    //设置到顶层节点
    QTreeWidgetItem* item = new QTreeWidgetItem();
    item->setText(0, str);
    ui->treeWidget->addTopLevelItem(item);
}
//添加到选中元素
void Widget::on_pushButton_item_add_clicked()
{
    //获取输入框中的本文内容
    const QString& str = ui->lineEdit->text();
    if(str.isEmpty())
        return;
    //获取选中元素
    QTreeWidgetItem* item = ui->treeWidget->currentItem();
    if(item == nullptr)
        return;
    //添加节点
    QTreeWidgetItem* new_item = new QTreeWidgetItem();
    new_item->setText(0, str);
    item->addChild(new_item);
    //设置展开父节点
    item->setExpanded(true);
}
//删除选中元素
void Widget::on_pushButton_item_del_clicked()
{
    //获取选中元素
    QTreeWidgetItem* item = ui->treeWidget->currentItem();
    if(item == nullptr)
        return;
    //获取父元素
    QTreeWidgetItem* parent = item->parent();
    //如果是顶层节点的话
    if(parent == nullptr)
    {
        //获取下标
        int index = ui->treeWidget->indexOfTopLevelItem(item);
        //删除
        ui->treeWidget->takeTopLevelItem(index);
    }
    //非顶层节点
    else
    {
        parent->removeChild(item);
    }
}








![[PAT 甲级] 1179 Chemical Equation (DFS)](https://i-blog.csdnimg.cn/direct/e02afaf95e724c5f8d69d46d8509af08.png)












