Summer:
QListWidget、QTableWidget 和 QTreeWidget 是 Qt 的 项视图部件(Item View Widgets),它们都是基于对应的视图类(QListView、QTableView、QTreeView)的便捷类,内部集成了默认的模型。
核心区别对比
| 特性 | QListWidget | QTableWidget | QTreeWidget |
|---|---|---|---|
| 数据维度 | 一维列表 | 二维表格 | 树形层次结构 |
| 继承自 | QListView | QTableView | QTreeView |
| 模型类型 | 内部 QListWidgetItem 列表 | 内部 QTableWidgetItem 表格 | 内部 QTreeWidgetItem 树 |
| 复杂度 | 简单 | 中等 | 复杂 |
| 典型用途 | 简单列表、选择框 | 数据表格、报表 | 目录树、分类结构 |
QListWidget 使用场景
特点:
-
最简单的项视图部件
-
直接操作项(QListWidgetItem),无需模型/视图架构
-
适合小型、简单的列表需求
适合场景:
-
简单的选择列表
cpp
QListWidget *listWidget = new QListWidget;
listWidget->addItem("选项1");
listWidget->addItem("选项2");
listWidget->addItem("选项3");
// 添加带图标的项
QListWidgetItem *item = new QListWidgetItem(QIcon("icon.png"), "带图标的项");
listWidget->addItem(item);
图标视图(缩略图浏览)
cpp
listWidget->setViewMode(QListWidget::IconMode);
listWidget->setIconSize(QSize(64, 64));
listWidget->setSpacing(10);
拖放排序
cpp
listWidget->setDragDropMode(QAbstractItemView::InternalMove);
listWidget->setDefaultDropAction(Qt::MoveAction);
- 简单的待办事项、文件列表、联系人列表
优点:
-
使用简单,无需设置模型
-
代码量少,适合快速原型
缺点:
-
数据量大时性能较差
-
功能有限,不适合复杂需求
QTableWidget 使用场景
特点:
-
二维表格控件
-
直接操作单元格(QTableWidgetItem)
适合场景:
-
小型数据表格
cpp
QTableWidget *tableWidget = new QTableWidget(3, 3);
tableWidget->setHorizontalHeaderLabels({"ID", "姓名", "年龄"});
// 设置单元格内容
tableWidget->setItem(0, 0, new QTableWidgetItem("001"));
tableWidget->setItem(0, 1, new QTableWidgetItem("张三"));
tableWidget->setItem(0, 2, new QTableWidgetItem("25"));
// 设置整行
QStringList rowData = {"002", "李四", "30"};
for (int col = 0; col < rowData.size(); ++col) {
tableWidget->setItem(1, col, new QTableWidgetItem(rowData[col]));
}
可编辑的数据表
cpp
// 允许编辑
tableWidget->setEditTriggers(QAbstractItemView::DoubleClicked |
QAbstractItemView::EditKeyPressed);
// 设置单元格为复选框
QTableWidgetItem *checkItem = new QTableWidgetItem();
checkItem->setCheckState(Qt::Unchecked);
tableWidget->setItem(0, 0, checkItem);
带有样式设置的表格
cpp
// 设置单元格背景色
QTableWidgetItem *item = tableWidget->item(0, 0);
item->setBackground(Qt::yellow);
item->setForeground(Qt::red);
// 设置对齐方式
item->setTextAlignment(Qt::AlignCenter);
- 小型数据库展示、设置表格、成绩单
优点:
-
直接操作单元格,直观易懂
-
内置编辑功能
-
支持单元格格式设置
缺点:
-
数据量大时性能差
-
内存占用较高(每个单元格都是对象)
QTreeWidget 使用场景

特点:
-
树形结构控件
-
层次化数据展示
适合场景:
-
文件系统浏览器
cpp
QTreeWidget *treeWidget = new QTreeWidget;
treeWidget->setColumnCount(2);
treeWidget->setHeaderLabels({"名称", "大小"});
// 添加根节点
QTreeWidgetItem *rootItem = new QTreeWidgetItem(treeWidget);
rootItem->setText(0, "C盘");
rootItem->setIcon(0, QIcon("drive.png"));
// 添加子节点
QTreeWidgetItem *folderItem = new QTreeWidgetItem(rootItem);
folderItem->setText(0, "Documents");
folderItem->setText(1, "2.5 GB");
QTreeWidgetItem *fileItem = new QTreeWidgetItem(folderItem);
fileItem->setText(0, "report.doc");
fileItem->setText(1, "1.2 MB");
// 展开所有节点
treeWidget->expandAll();
分类目录结构
cpp
// 多级分类
QTreeWidgetItem *electronics = new QTreeWidgetItem(treeWidget);
electronics->setText(0, "电子产品");
QTreeWidgetItem *phones = new QTreeWidgetItem(electronics);
phones->setText(0, "手机");
QTreeWidgetItem *apple = new QTreeWidgetItem(phones);
apple->setText(0, "iPhone");
apple->setData(0, Qt::UserRole, "product_id_001"); // 存储额外数据
带复选框的树(权限设置)
cpp
QTreeWidgetItem *item = new QTreeWidgetItem;
item->setText(0, "权限选项");
item->setCheckState(0, Qt::Unchecked);
treeWidget->addTopLevelItem(item);
- 组织结构图、产品分类、设置选项分组
优点:
-
直观展示层次关系
-
支持无限级嵌套
-
可以存储额外数据(setData)
缺点:
-
复杂的数据操作较为繁琐
-
性能随深度增加而下降
选择指南
选择 QListWidget 当:
-
数据量小(< 1000项)
-
只需要简单列表显示
-
不需要复杂的数据操作
-
快速开发原型
-
示例:语言选择列表、字体大小选择、颜色列表
选择 QTableWidget 当:
-
数据量适中(< 1000行×10列)
-
需要表格形式展示
-
需要单元格级别的格式控制
-
不需要频繁的数据更新
-
示例:学生成绩表、产品价格表、配置表格
选择 QTreeWidget 当:
-
数据具有层次结构
-
需要展开/折叠功能
-
数据量适中(深度不宜过深)
-
示例:文件浏览器、组织架构、分类目录
性能考虑
大数据量场景:不要使用 Widget 类!
cpp
// ❌ 错误:大数据量使用 Widget 类
QListWidget *list = new QListWidget;
for (int i = 0; i < 100000; i++) {
list->addItem(QString("Item %1").arg(i));
}
// 这将导致界面卡顿、内存占用高
// ✅ 正确:大数据量使用 Model/View 架构
QListView *view = new QListView;
QStringListModel *model = new QStringListModel;
QStringList data;
for (int i = 0; i < 100000; i++) {
data << QString("Item %1").arg(i);
}
model->setStringList(data);
view->setModel(model);
总结对比表
| 场景 | 推荐控件 | 理由 |
|---|---|---|
| 简单单选列表 | QListWidget | 使用简单,代码少 |
| 多列数据展示 | QTableWidget | 表格操作直观 |
| 层次数据 | QTreeWidget | 天然支持树形结构 |
| 大数据量 | QListView/QTableView/QTreeView + 自定义模型 | 性能好,内存占用低 |
| 需要自定义显示 | 对应 View 类 + 自定义委托 | 灵活度高 |
| 需要复杂数据操作 | 对应 View 类 + 自定义模型 | 分离数据与视图 |
| 快速原型开发 | *Widget 类 | 开发速度快 |
通用技巧
cpp
// 1. 搜索功能(适用于所有三个控件)
void searchItems(QTreeWidget *tree, const QString &text) {
for (int i = 0; i < tree->topLevelItemCount(); ++i) {
QTreeWidgetItem *item = tree->topLevelItem(i);
item->setHidden(!item->text(0).contains(text, Qt::CaseInsensitive));
}
}
// 2. 右键菜单
treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
connect(treeWidget, &QTreeWidget::customContextMenuRequested,
[=](const QPoint &pos) {
QMenu menu;
menu.addAction("添加");
menu.addAction("删除");
menu.exec(treeWidget->viewport()->mapToGlobal(pos));
});
// 3. 排序
tableWidget->setSortingEnabled(true);
tableWidget->sortByColumn(0, Qt::AscendingOrder);
记住:对于简单、小数据量的需求,使用 *Widget 类更方便;对于复杂、大数据量或需要高度定制的需求,使用 Model/View 架构。