【Qt常用控件】—— 多元素控件

目录

[1.1 List Widget](#1.1 List Widget)

[1.2 Table Widget](#1.2 Table Widget)

[1.3 Tree Widget](#1.3 Tree Widget)

[1.4 小结](#1.4 小结)


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

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

xxWidget 和 xxView 之间的区别
以 QTableWidget 和 QTableView 为例:

  1. QTableView 是基于 MVC 设计的控件. QTableView ⾃⾝不持有数据. 使⽤ QTableView的时候需要⽤⼾创建⼀个 Model 对象 (⽐如 QStandardModel ), 并且把 Model 和QTableView 关联起来. 后续修改 Model 中的数据就会影响 QTableView 的显⽰; 修改QTableView 的显⽰也会影响到 Model 中的数据(双向绑定).
  2. QTableWidget 则是 QTableView 的子类, 对 Model 进⾏了封装. 不需要⽤⼾⼿动创建Model 对象, 直接就可以往 QTableWidget 中添加数据了.

1.1 List Widget

在Qt中,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 ⾮空. 初始情况下是没有元素选中的, 就导致这俩指针可能是 NULL.
cpp 复制代码
void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current,
QListWidgetItem *previous)
{
     if (current != NULL && previous != NULL) {
         qDebug() << "当前选中: " << current->text()<< "之前选中: " << previous->text();
     }
}
  • 这⾥需要给 widget.h 前⾯加上 #include <QListWidgetItem>

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) 执⾏程序, 观察效果. 可以新增元素, 选中元素, 删除元素.


1.2 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 和 三个按钮, ⼀个输⼊框

  • 注意: QTableWidget 是 QTableView 的⼦类, 功能⽐ QTableView 更丰富. 咱们使用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, new QTableWidgetItem(name));
}

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

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

  1. 默认情况下, 单元格中的内容直接就是可编辑的.
  2. 如果不想让用户进行编辑,可以设置
cpp 复制代码
ui>tableWidget>setEditTriggers(QAbstractItemView::NoEditTriggers);

1.3 Tree Widget

  1. 使⽤ QTreeWidget 表⽰⼀个树形控件. ⾥⾯的每个元素, 都是⼀个 QTreeWidgetItem , 每个 QTreeWidgetItem 可以包含多个⽂本和图标, 每个⽂本/图标为⼀个列.
  2. 可以给 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 和两个按 钮.

  • 注意: TreeWidget 是 TreeView 的⼦类, 功能⽐ TreeView 更丰富. 咱们使⽤ TreeWidget即可.

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


1.4 小结

QListWidgetQTableWidgetQTreeWidget 是 Qt 中常用的三种用于展示列表、表格和树形结构数据的控件,它们各自有着不同的特点和用法。

QListWidget

  • 特点:用于显示简单的列表,每个列表项可以包含文本、图标等简单内容。
  • 用途:适用于简单的列表展示,如文件列表、选项列表等。

QTableWidget

  • 特点:用于显示二维表格数据,支持行列操作、单元格编辑等功能。
  • 用途:适用于显示表格数据,如数据展示、编辑表格等。

QTreeWidget

  • 特点:用于显示树形结构数据,支持展开折叠、节点操作等功能。
  • 用途:适用于显示层级结构数据,如文件夹结构、树状菜单等。

总结

  • 使用 QListWidget 来显示简单的列表数据。
  • 使用 QTableWidget 来显示二维表格数据。
  • 使用 QTreeWidget 来显示树形结构数据。

这些控件都提供了丰富的功能和灵活的接口,可以根据实际需求选择合适的控件来展示数据。

相关推荐
yutian060613 分钟前
C# TextBox 控件限制输入字符为十六进制字符串
开发语言·c#
猛犸MAMMOTH19 分钟前
Python打卡第51天
开发语言·python·深度学习
小安同学iter23 分钟前
JUC并发编程(四)常见模式
java·开发语言
海风极客1 小时前
《Go小技巧&易错点100例》第三十五篇
开发语言·后端·golang
YuTaoShao1 小时前
Java八股文——Spring「SpringMVC 篇」
java·开发语言·spring
程序员JerrySUN1 小时前
Linux 内存管理实战精讲:核心原理与面试常考点全解析
linux·运维·开发语言·嵌入式硬件·架构
CodeWithMe1 小时前
【C/C++】long long 类型传参推荐方式
c语言·开发语言·c++
ch_s_t1 小时前
Babylon.js引擎(二)
开发语言·javascript·ecmascript
Shaun_青璇2 小时前
CPP基础(2)
开发语言·c++·算法
景天科技苑2 小时前
【Rust UDP编程】rust udp编程方法解析与应用实战
开发语言·rust·udp·udp编程·rust udp