目录
1. List Widget
代码示例:使用 ListWidget(增删选)
2. Table Widget
代码示例:使用 QTableWidget
3. Tree Widget
代码示例:使用 QTreeWidget
Qt 中提供的多元素控件:
- QListWidget
- QListView
- QTableWidget
- QTableView
- QTreeWidget
- QTreeView
xxWidget 和 xxView 之间的区别,以 QTableWidget 和 QTableView 为例。
- QTableView 是基于 MVC 设计的控件。QTableView 自身不持有数据。使用 QTableView 的时候需要用户创建一个 Model 对象(比如 QStandardItemModel),并且把 Model 和 QTableView 关联起来。后续修改 Model 中的数据就会影响 QTableView 的显示;修改 QTableView 的显示也会影响到 Model 中的数据(双向绑定)。
- QTableWidget 则是 QTableView 的子类,对 Model 进行了封装。不需要用户手动创建 Model 对象,直接就可以往 QTableWidget 中添加数据了。
1. 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(增删选)
- 在界面上创建一个 ListView,右键=>变形为=>ListWidget,再创建一个 lineEdit 和两个按钮。
注意:ListWidget 是 ListView 的子类,功能比 ListView 更丰富。咱们使用 ListWidget 即可。
- 编写 widget.cpp,在构造函数中添加初始元素
- 编写 listWidget 的 slot 函数
- 编写按钮的 slot 函数
这里需要给 widget.h 前面加上 #include
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"); } // 此处需要判定 current 和 previous 非空 // 初始情况下是没有元素选中的,就导致这俩指针可能是 NULL。 void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) { if (current != NULL && previous != NULL) { qDebug() << "当前选中: " << current->text()<< "之前选中: " << previous->text(); } } 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); }2. Table Widget
使用 QTableWidget 表示一个表格控件。一个表格中包含若干行,每一行又包含若干列。
表格中的每个单元格,是一个 QTableWidgetItem 对象。
QTableWidget 核心方法
| 方法 | 说明 |
|---|---|
| item(int row, int column) | 根据行数列数获取指定的 QTableWidgetItem* |
| setItem(int row, int column, QTableWidgetItem*) | 根据行数列数设置表格中的元素 |
| 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, QTableWidgetItem*) | 设置指定列的表头 |
| setVerticalHeaderItem(int row, QTableWidgetItem*) | 设置指定行的表头 |
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
在界面上创建 QTableWidget 和三个按钮,一个输入框
注意:QTableWidget 是 QTableView 的子类,功能比 QTableView 更丰富。咱们使用 QTableWidget 即可
- 编写 widget.cpp 构造函数,构造表格中的初始数据。
- 编写按钮的 slot 函数
- 执行程序,即可完成表格的基本操作。
默认情况下,单元格中的内容直接就是可编辑的。如果不想让用户编辑,可以设置
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);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")); }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, new QTableWidgetItem(name)); } void Widget::on_pushButton_delCol_clicked() { // 1. 获取选中的列号 int curCol = ui->tableWidget->currentColumn(); // 2. 删除对应的列 ui->tableWidget->removeColumn(curCol); }3. 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) | 元素被展开时触发 |
| itemCollapsed(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
在界面上创建一个 TreeView,右键=>变形为=>TreeWidget,再创建一个 lineEdit 和两个按钮。
注意:TreeWidget 是 TreeView 的子类,功能比 TreeView 更丰富。咱们使用 TreeWidget 即可。
- 编写代码,构造初始数据
- 编写代码,实现按钮的 slot 函数
- 执行程序,可以针对树形框进行编辑
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); }// 添加到顶层元素中 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); } }