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) 执行程序, 可以针对树形框进行编辑.

相关推荐
nbsaas-boot1 小时前
Java 正则表达式白皮书:语法详解、工程实践与常用表达式库
开发语言·python·mysql
岁忧1 小时前
(LeetCode 面试经典 150 题 ) 11. 盛最多水的容器 (贪心+双指针)
java·c++·算法·leetcode·面试·go
chao_7891 小时前
二分查找篇——搜索旋转排序数组【LeetCode】两次二分查找
开发语言·数据结构·python·算法·leetcode
风无雨2 小时前
GO 启动 简单服务
开发语言·后端·golang
斯普信专业组2 小时前
Go语言包管理完全指南:从基础到最佳实践
开发语言·后端·golang
哈市雪花3 小时前
相机:以鼠标点为中心缩放(使用OpenGL+QT开发三维CAD)
qt·相机·opengl·cad·缩放·工业软件·渲染效果
我是苏苏4 小时前
C#基础:Winform桌面开发中窗体之间的数据传递
开发语言·c#
斐波娜娜4 小时前
Maven详解
java·开发语言·maven
小码氓4 小时前
Java填充Word模板
java·开发语言·spring·word
暮鹤筠5 小时前
[C语言初阶]操作符
c语言·开发语言