目录
一,关于多元素控件
二,QListWidget
2.1 主要方法
2.2 实现新增删除
三,Table Widget
3.1 主要方法
3.2 代码演示
四,Tree Widget
4.1 主要方法
4.2 代码演示
一,关于多元素控件
多元素控件就是一个控件里面包含了很多的元素,可能是字符串,也可能是复杂的数据结构、图片等等,多元素控件有很多,典型的有6个:
- 列表:QListWidget,QListView
- 表格:QTableWidget,QTableView
- 树形:QTreeWidget,QTreeView
可以发现,说是6个控件,其实是3个,只是两两一组而已
问题:xxWidget 和 xxView 是什么关系?
解答:
- 可以理解为 xxView 是很底层的实现,然后 xxWidget 是基于 xxView 的封装而来
- xxView 是 MVC 结构的一种典型实现,但 xxView 只负责实现了食物,不负责数据如何存储显示,也不负责数据和视图之间的交互
- 因此程序猿需要自动实现 model 和 controller 部分来使用 xxView,比较麻烦
- 所以Qt 为我们提供了 xxWidget,为我们实现好了 model 和 controller 并提供了功能很方便的 API,我们直接用就好
问题:什么是MVC?
解答: MVC 全称 “Model-View-Controller”,是一种软件涉及典范,是软件开发中非常经典的一种软件结构
- M:model,表示模型,或者叫数据,负责存取数据,并在数据变化时更新控制器
- V:view,表示视图,或者叫界面,负责展示模型中的数据,并提供用户界面
- C:Controller,表示控制器,是处理模型和视图之间的业务流程,接收用户输入,并调用模型和视图去完成用户的需求
二,QListWidget
2.1 主要方法
QListWidget 能够显示一个纵向的列表,并且每个选项都可以被选中, 和下拉按钮行为类似
主要属性:
属性 | 说明 |
---|---|
currentRow | 当前被选中的是第几行 |
count | 一共多少行 |
sortingEnabled | 是否允许排序 |
isWrapping | 是否允许换行 |
itemAlignment | 元素的对齐方式 |
selectRectVisible | 被选中的元素矩阵是否可见(默认背景蓝色) |
spacing | 元素之间的间隔 |
常用的函数如下:
函数 | 说明 |
---|---|
addItem(const QString& label) addItem(QListWidgetItem* item) | 列表中添加元素 列表中的每一项称为一个item,具体的说通过 QListWidgetgetItme 类表示的 |
currentItem() | 返回 QListWidgetgetItem* 表示当前选中的元素 |
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 | 设置文本对齐方式 |
2.2 实现新增删除
先创建下列控件:
两个都可以,因为可以转换,如下:
代码如下:
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
#include<QShortcut>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// ui->listWidget->addItem("C++");
// ui->listWidget->addItem("Pyhton");
// ui->listWidget->addItem("Java");ui->listWidget->addItem(new QListWidgetItem("C++"));ui->listWidget->addItem(new QListWidgetItem("Python"));ui->listWidget->addItem(new QListWidgetItem("Java"));//两种方式都可以添加,也可以直接在ui界面例右键编辑项目添加//QListWidgetItem 也可以设置字体属性,图标,大小等等
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_insert_clicked()
{const QString& text = ui->lineEdit->text(); //先获取输入框的内容ui->listWidget->addItem(text); //将内容添加到表格里
}void Widget::on_pushButton_delete_clicked()
{int row = ui->listWidget->currentRow(); //先获取被选中的元素if(row < 0) return;ui->listWidget->takeItem(row);
}
效果如下:
三,Table Widget
3.1 主要方法
这个表示一个表格控件,简单来说就是就是类似二维数组的结构,表格中的每个单元格是一个 QTableWidgetItem 对象,常用方法如下:
方法 | 说明 |
---|---|
item(int row, int column) | 根据行数列数获取指定的 QtableWidgetItem* |
item(int row, int column) | 根据行数列数设置表格中的元素 |
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(introw, QTableWidget*) | 设置指定行的表头 |
主要的信号如下:
信号 | 说明 |
---|---|
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 和上面的 QListWidgetItem 类似,主要方法如下:
方法 | 说明 |
---|---|
row() | 获取当前是第几行 |
column() | 获取当前是第几列 |
setText(const QString&) | 设置文本 |
setTextAlignment(int) | 设置文本对齐 |
setIcon(const QIcon&) | 设置图标 |
setSelected(bool) | 设置被选中 |
setSizeHints(const QSize&) | 设置尺寸 |
setFont(const QFont&) | 设置字体 |
3.2 代码演示
先创建下列控件:
我们先往表格里添加部分元素,在代码添加太麻烦,所以我们这里直接右键编辑项目添加:
所以下面我们也使用文件来进行初始化数据,通过代码初始化表格:
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);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("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("1003"));ui->tableWidget->setItem(2, 1, new QTableWidgetItem("王五"));ui->tableWidget->setItem(2, 2, new QTableWidgetItem("19"));
}
四个槽函数实现如下:
void Widget::on_pushButton_addRow_clicked()
{int rowCount = ui->tableWidget->rowCount(); //获取总行数ui->tableWidget->insertRow(rowCount); //在最后一行新增行,这个参数是下标,所以不需要 + 1
}void Widget::on_pushButton_subRow_clicked()
{int subRow = ui->tableWidget->currentRow(); //获取到选中的行号ui->tableWidget->removeRow(subRow); //删除这一行
}void Widget::on_pushButton_addColumn_clicked()
{int columnCount = ui->tableWidget->columnCount(); //获取总列数ui->tableWidget->insertColumn(columnCount); //在最后一列添加列const QString& text = ui->lineEdit->text(); //获取输入框里的列名ui->tableWidget->setHorizontalHeaderItem(columnCount, new QTableWidgetItem(text)); //给新增列添加列名
}void Widget::on_pushButton_subColumn_clicked()
{int subColumn = ui->tableWidget->currentColumn(); //获取选中的列号ui->tableWidget->removeColumn(subColumn);
}
效果如下:
默认情况下表格内容是可编辑的,但是如果不想让用户编辑,可以设置下列属性:
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
四,Tree Widget
4.1 主要方法
QTreeWidget 表示一个树形控件,里面的每个元素都是一个 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(constQString& text) | 设置TreeWidget 的 header 名称 |
关于顶层节点:
上面的顶层节点,并不是单指根节点,因为QTreeWidget 的树形结构,没有体现出根节点,是从根节点的下一层子节点开始计算的,如下图:
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() | 获取该元素的父节点 |
4.2 代码演示
先创建下列控件:
初始化数据我们可以通过 ui界面右键编辑项目直接添加,也可以通过代码添加,和上面的表格是一样的,下面是通过代码初始化元素的代码:
//篇幅原因这里也只添加部分元素
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);
}
下面是三个按钮的槽函数实现:
void Widget::on_pushButton_insertTopLevelItem_clicked()
{const QString& text = ui->lineEdit->text(); //获取输入框内容QTreeWidgetItem* item = new QTreeWidgetItem();//构造 QTreeWidget 对象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* item = new QTreeWidgetItem();//构造 QTreeWidget 对象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); //普通元素直接删除即可}
}
上述几个控件相关的操作,数据都是在内存中保存的,重新运行程序后,数据都会重置
所以要想数据不被丢失,就得需要和“学生管理系统”一样,实现一个“保存数据到文件”和“从文件读取数据”的两个操作,每次运行程序时读取文件数据,每次关闭程序时,在析构函数里添加保存文件的操作