文章目录
- [1. 继承关系和本质区别](#1. 继承关系和本质区别)
- [2. 使用方式区别](#2. 使用方式区别)
-
- [QListWidget 的使用方式](#QListWidget 的使用方式)
- [QListView 的使用方式](#QListView 的使用方式)
- [3. 功能层面对比](#3. 功能层面对比)
- [4. 适用场景区别](#4. 适用场景区别)
-
- [适合用 QListWidget 的场景](#适合用 QListWidget 的场景)
- [适合用 QListView 的场景](#适合用 QListView 的场景)
- [5. 数据管理区别](#5. 数据管理区别)
- [6. 自定义展示能力区别](#6. 自定义展示能力区别)
-
- [QListWidget 自定义](#QListWidget 自定义)
- [QListView 自定义](#QListView 自定义)
- [7. 性能和扩展性区别](#7. 性能和扩展性区别)
- [8. 信号和操作区别](#8. 信号和操作区别)
-
- [QListWidget 常用信号](#QListWidget 常用信号)
- [QListView 常用信号](#QListView 常用信号)
- [9. 两者代码示例对比](#9. 两者代码示例对比)
-
- 示例1:简单字符串列表
-
- [QListWidget 写法](#QListWidget 写法)
- [QListView 写法](#QListView 写法)
- 示例2:后续需要动态更新数据
-
- QListWidget
- [QListView + Model](#QListView + Model)
- [示例3:复杂列表(头像 + 名称 + 状态)](#示例3:复杂列表(头像 + 名称 + 状态))
- [10. 实际开发建议](#10. 实际开发建议)
-
- [选 QListWidget,如果:](#选 QListWidget,如果:)
- [选 QListView,如果:](#选 QListView,如果:)
- [11. 一个通俗类比](#11. 一个通俗类比)
- [12. 结论](#12. 结论)
QListWidget 是 基于项(item-based) 的列表控件, QListView 是 基于模型/视图(model-view) 的列表视图。
一句话区别:
- QListWidget:简单、直接、适合小型列表
- QListView:灵活、可扩展、适合复杂数据展示
1. 继承关系和本质区别
QListWidget
QListWidget 本质上是对 QListView 的进一步封装,内部已经帮你维护好了数据模型。
你直接往里面加 QListWidgetItem 就能显示。
特点:
- 使用简单
- 不需要自己写模型
- 适合静态或简单列表
- 开发效率高
QListView
QListView 只是"视图",自己不存数据,数据需要来自模型,例如:
QStringListModelQStandardItemModel- 自定义
QAbstractListModel
特点:
- 数据和界面分离
- 更适合复杂业务
- 更容易做排序、过滤、复用
- 更适合大规模数据
2. 使用方式区别
QListWidget 的使用方式
直接添加 item:
cpp
QListWidget *listWidget = new QListWidget(this);
listWidget->addItem("苹果");
listWidget->addItem("香蕉");
listWidget->addItem("橙子");
你操作的是:
QListWidgetQListWidgetItem
不需要额外模型。
QListView 的使用方式
必须先准备模型,再绑定视图:
cpp
QStringListModel *model = new QStringListModel(this);
model->setStringList({"苹果", "香蕉", "橙子"});
QListView *listView = new QListView(this);
listView->setModel(model);
你操作的是:
QListViewModel
视图只负责显示。
3. 功能层面对比
| 对比项 | QListWidget | QListView |
|---|---|---|
| 使用难度 | 简单 | 较高 |
| 是否需要模型 | 不需要手动写 | 必须有模型 |
| 数据和界面分离 | 否 | 是 |
| 适合场景 | 简单、小型列表 | 复杂、动态、大型列表 |
| 扩展性 | 一般 | 很强 |
| 自定义能力 | 较弱 | 很强 |
| 排序/过滤 | 能做,但不优雅 | 更规范,通常配合代理模型 |
| 复用业务数据 | 较差 | 很好 |
4. 适用场景区别
适合用 QListWidget 的场景
如果你的列表只是简单显示几个选项,比如:
- 最近打开文件
- 简单菜单项
- 配置页中的固定选项列表
- 小型测试工具界面
例如:
cpp
QListWidget *listWidget = new QListWidget(this);
listWidget->addItem("新建项目");
listWidget->addItem("打开项目");
listWidget->addItem("退出");
这种场景用 QListWidget 最省事。
适合用 QListView 的场景
如果你的数据来自业务层、数据库、网络、文件系统,或者后续需要扩展:
- 用户列表
- 日志列表
- 搜索结果列表
- 文件列表
- 设备列表
- 支持过滤/排序/分页的数据列表
例如:
cpp
QStringListModel *model = new QStringListModel(this);
model->setStringList({"设备A", "设备B", "设备C"});
QListView *listView = new QListView(this);
listView->setModel(model);
如果以后数据变化,只需要更新模型,界面会自动刷新。
5. 数据管理区别
QListWidget
数据保存在控件内部。
你往控件加 item,本质上是"控件管理数据"。
例如删除一项:
cpp
delete listWidget->takeItem(1);
这种方式简单,但当数据逻辑复杂时,UI 和数据容易耦合在一起。
QListView
数据由模型管理。
视图只负责显示模型里的内容。
例如更新数据:
cpp
model->setStringList({"北京", "上海", "深圳"});
这样业务数据和界面职责更清晰。
6. 自定义展示能力区别
QListWidget 虽然也能自定义 item,但复杂度一上来就不如 QListView + Model + Delegate 自然。
QListWidget 自定义
可以给每个 item 设置文字、图标:
cpp
QListWidgetItem *item = new QListWidgetItem(QIcon(":/img/a.png"), "图片1");
listWidget->addItem(item);
QListView 自定义
可以通过:
- 自定义模型
- 自定义委托
QStyledItemDelegate
实现复杂样式,比如:
- 一行显示标题 + 副标题
- 左侧头像,右侧用户名和状态
- 自定义选中效果
- 不同数据类型不同绘制样式
这类复杂列表,QListView 更适合。
7. 性能和扩展性区别
QListWidget
对于少量数据问题不大。
但如果数据很多,或者频繁刷新、动态更新,就不够灵活。
QListView
更适合:
- 大数据量
- 动态加载
- MVC 架构
- 后续维护扩展
尤其在工程项目中,规范写法通常更偏向 QListView + Model。
8. 信号和操作区别
QListWidget 常用信号
cpp
connect(listWidget, &QListWidget::itemClicked, this, [](QListWidgetItem *item){
qDebug() << item->text();
});
直接拿到 item,对简单场景非常方便。
QListView 常用信号
cpp
connect(listView, &QListView::clicked, this, [model](const QModelIndex &index){
qDebug() << model->data(index).toString();
});
拿到的是 QModelIndex,再通过模型取数据。
这种方式更通用,也更符合 Qt 的 MVC 设计。
9. 两者代码示例对比
示例1:简单字符串列表
QListWidget 写法
cpp
QListWidget *listWidget = new QListWidget(this);
listWidget->addItem("C++");
listWidget->addItem("Qt");
listWidget->addItem("Python");
connect(listWidget, &QListWidget::itemClicked, this, [](QListWidgetItem *item){
qDebug() << "点击了:" << item->text();
});
QListView 写法
cpp
QStringListModel *model = new QStringListModel(this);
model->setStringList({"C++", "Qt", "Python"});
QListView *listView = new QListView(this);
listView->setModel(model);
connect(listView, &QListView::clicked, this, [model](const QModelIndex &index){
qDebug() << "点击了:" << model->data(index).toString();
});
示例2:后续需要动态更新数据
QListWidget
cpp
listWidget->clear();
listWidget->addItem("任务1");
listWidget->addItem("任务2");
listWidget->addItem("任务3");
QListView + Model
cpp
QStringList tasks;
tasks << "任务1" << "任务2" << "任务3";
model->setStringList(tasks);
如果数据源来自业务对象,QListView 更容易统一管理。
示例3:复杂列表(头像 + 名称 + 状态)
QListWidget
理论上也能做,但会比较别扭,后续维护复杂。
QListView
推荐方式:
- 自定义
QAbstractListModel - 配合
QStyledItemDelegate - 控制绘制和交互
更适合真正项目开发。
10. 实际开发建议
选 QListWidget,如果:
- 只是简单列表
- 数据量不大
- 快速开发原型
- 不需要复杂扩展
- 界面逻辑很轻
选 QListView,如果:
- 数据来自业务层
- 需要统一架构
- 列表样式复杂
- 需要排序/过滤
- 数据经常变化
- 项目可维护性要求高
11. 一个通俗类比
- QListWidget:像"自带内容的现成表格",拿来就能用。
- QListView:像"空白展示框",你要自己提供数据源,但因此更灵活。
12. 结论
最核心区别可以记成一句话:
QListWidget是方便使用的现成列表控件;
QListView是更底层、更灵活的列表视图,需要配合模型使用。
如果你只是做简单页面,QListWidget 很方便;
如果你要做规范项目、统一 UI、复杂列表展示,通常更建议使用 QListView。