【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 来显示树形结构数据。

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

相关推荐
用户805533698035 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner5 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz10 天前
QML Hello World 入门示例
qt
xcyxiner13 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner14 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner14 天前
DicomViewer (添加模型类)3
qt
xcyxiner15 天前
DicomViewer (目录调整) 2
qt
xcyxiner15 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00617 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术17 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript