Qt 多元素控件

Qt开发 多元素控件

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

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

xxWidget 和 xxView 之间的区别

以 QTableWidget 和 QTableView 为例.

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

List Widget

使用 QListWidget 能够显示一个纵向的列表. 形如

每个选项都可以被选中.

核心属性

属性 说明
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 即可

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

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

(3) 编写 listWidget 的 slot 函数

此处需要判定 current 和 previous 非空. 初始情况下是没有元素选中的, 就导致这俩指针可能是 nullptr.

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

(4) 编写按钮的 slot 函数

cpp 复制代码
void Widget::on_pushButton_clicked()
{
	// 获取到输⼊框的内容
	const QString& text = ui->lineEdit->text();
	if (text.isEmpty()) {
		return;	
	}
	ui->listWidget->addItem(text);
}

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

(5) 执行程序,观察效果.可以新增元素,选中元素,删除元素

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 和 三个按钮, 一个输入框

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

cpp 复制代码
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("1003"));
	ui->tableWidget->setItem(2, 1, new QTableWidgetItem("王五"));
	ui->tableWidget->setItem(2, 2, new QTableWidgetItem("19"));
}

(3) 编写按钮的 slot 函数

cpp 复制代码
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);
	// 3. 设置列名
	const QString& name = ui->lineEdit->text();
	ui->tableWidget->setHorizontalHeaderItem(colCount, newQTableWidgetItem(name));
}

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

(4) 执行程序, 即可完成表格的基本操作.

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

如果不想让用户编辑, 可以设置 ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);

Tree Widget

使用 QTreeWidget 表示一个树形控件,里面的每个元素,都是一个 TreeWidgetItem,每个 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 和两个按钮

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

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

(3) 编写代码, 实现按钮的 slot 函数

cpp 复制代码
//添加到顶层节点中
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);
	}
}

(4) 执行程序, 可以针对树形框进行编辑.

相关推荐
脚大江山稳9 分钟前
二进制与十进制互转的方法
c++
shykevin4 小时前
python开发Streamable HTTP MCP应用
开发语言·网络·python·网络协议·http
我不是程序猿儿4 小时前
【C#】 lock 关键字
java·开发语言·c#
漫路在线5 小时前
JS逆向-某易云音乐下载器
开发语言·javascript·爬虫·python
小辉懂编程5 小时前
C语言:51单片机实现数码管依次循环显示【1~F】课堂练习
c语言·开发语言·51单片机
醍醐三叶6 小时前
C++类与对象--2 对象的初始化和清理
开发语言·c++
Magnum Lehar7 小时前
3d游戏引擎EngineTest的系统实现3
java·开发语言·游戏引擎
Mcworld8577 小时前
java集合
java·开发语言·windows
成功人chen某7 小时前
配置VScodePython环境Python was not found;
开发语言·python
wuqingshun3141598 小时前
蓝桥杯 16. 外卖店优先级
c++·算法·职场和发展·蓝桥杯·深度优先