news 2026/6/9 22:03:13

PySide6之QListView 学习

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PySide6之QListView 学习

QListView 是 PySide6 中用于展示列表数据的核心控件,属于 Model/View 架构的一部分(与 QListWidget 不同,QListWidget 是封装了 Model 的便捷控件,而 QListView 需配合数据模型使用)。它支持自定义数据展示、批量操作、排序 / 筛选等高级功能。

一、核心特性

Model/View 解耦:数据与界面分离,通过 Model 管理数据,View 仅负责展示,便于数据复用和维护。

灵活的显示模式:支持列表(List)、图标(Icon)、详情(Details)等模式(需配合 QStandardItemModel 或自定义 Model)。

自定义委托(Delegate):可定制列表项的绘制样式、编辑逻辑。

交互支持:多选、拖拽、编辑、右键菜单等。

性能优化:懒加载、虚拟滚动,适合海量数据展示。

二、使用范例

  • 基础使用
import sys from PySide6.QtCore import QStringListModel from PySide6.QtWidgets import QApplication, QListView, QVBoxLayout, QWidget class MainWindow(QWidget): def __init__(self): super().__init__() self.setWindowTitle("QListView 基础示例") self.resize(400, 300) # 1. 创建布局 layout = QVBoxLayout(self) # 2. 创建 QListView self.list_view = QListView() layout.addWidget(self.list_view) # 3. 创建数据模型(QStringListModel 仅支持字符串) self.model = QStringListModel() # 设置初始数据 self.model.setStringList(["Python", "PySide6", "QListView", "Model/View"]) # 4. 将模型绑定到 QListView self.list_view.setModel(self.model) # 5. 可选:设置交互属性 self.list_view.setEditTriggers(QListView.EditTrigger.DoubleClicked) # 双击编辑 self.list_view.setSelectionMode(QListView.SelectionMode.ExtendedSelection) # 多选 self.list_view.setSpacing(3) # 列表项间距 if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())

  • 支持多列、自定义数据(图标、复选框、自定义角色):
import sys from PySide6.QtCore import QModelIndex, Qt from PySide6.QtGui import QStandardItemModel, QStandardItem from PySide6.QtWidgets import QApplication, QListView, QVBoxLayout, QWidget, QMainWindow class AdvancedListView(QWidget): def __init__(self): super().__init__() self.setWindowTitle("QListView 进阶示例") self.resize(400, 300) layout = QVBoxLayout(self) # 1. 创建 QListView self.list_view = QListView() layout.addWidget(self.list_view) # 2. 创建 QStandardItemModel(支持复杂数据) self.model = QStandardItemModel() # 添加带图标、复选框的项 items = [ ("Python", False), ("PySide6", False), ("QListView", False), ("Model/View", False) ] for text, checked in items: item = QStandardItem(text) item.setCheckable(True) # 启用复选框 item.setCheckState(Qt.CheckState.Checked if checked else Qt.CheckState.Unchecked) # 设置初始状态 # 自定义数据(通过角色存储) item.setData(f"描述:{text}", Qt.ItemDataRole.UserRole) self.model.appendRow(item) # 3. 绑定模型 self.list_view.setModel(self.model) # 4. 信号绑定(选中项变化) self.list_view.selectionModel().currentChanged.connect(self.on_current_changed) def on_current_changed(self, current: QModelIndex, previous: QModelIndex): """选中项变化时触发""" if current.isValid(): # 获取项的文本 text = current.data(Qt.ItemDataRole.DisplayRole) # 获取自定义数据 desc = current.data(Qt.ItemDataRole.UserRole) # 获取复选框状态 check_state = current.data(Qt.ItemDataRole.CheckStateRole) print(f"选中:{text} | {desc} | 复选框:{check_state}") if __name__ == "__main__": app = QApplication(sys.argv) window = AdvancedListView() window.show() sys.exit(app.exec())

三、关键配置与属性

1. 显示模式

# 设置为列表模式(默认) self.list_view.setViewMode(QListView.ViewMode.ListMode) # 设置为图标模式(类似桌面图标) self.list_view.setViewMode(QListView.ViewMode.IconMode) # 图标模式下的图标大小 self.list_view.setIconSize(QSize(32, 32)) # 换行(ListMode 下是否自动换行) self.list_view.setWrapping(True)

2. 选择模式

模式说明
QListView.NoSelection不可选
QListView.SingleSelection单选
QListView.MultiSelection多选(点击切换)
QListView.ExtendedSelection扩展多选(Ctrl/Shift 辅助)
QListView.ContiguousSelection连续多选(拖拽选择)
  • 配置示例:
self.list_view.setSelectionMode(QListView.SelectionMode.ExtendedSelection) # 设置选择行为(选中整行/仅文本) self.list_view.setSelectionBehavior(QListView.SelectionBehavior.SelectRows)

3. 编辑触发方式

# 双击编辑 self.list_view.setEditTriggers(QListView.EditTrigger.DoubleClicked) # 点击编辑 self.list_view.setEditTriggers(QListView.EditTrigger.SelectedClicked) # 禁止编辑 self.list_view.setEditTriggers(QListView.EditTrigger.NoEditTriggers) # 多种触发方式(组合) self.list_view.setEditTriggers( QListView.EditTrigger.DoubleClicked | QListView.EditTrigger.AnyKeyPressed )

4. 布局与外观

# 列表项间距 self.list_view.setSpacing(8) # 边距 self.list_view.setContentsMargins(10, 10, 10, 10) # 启用网格布局(IconMode 下) self.list_view.setGridSize(QSize(100, 50)) # 隐藏横向滚动条 self.list_view.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) # 设置字体 font = self.list_view.font() font.setPointSize(12) self.list_view.setFont(font)

四、常用信号与交互

1. 核心信号

信号说明
clicked(QModelIndex)点击项时触发
doubleClicked(QModelIndex)双击项时触发
activated(QModelIndex)激活项(回车 / 双击)时触发
selectionModel().currentChanged选中项变化时触发
pressed(QModelIndex)按下鼠标时触发

2. 获取选中项

# 获取所有选中的索引 selected_indexes = self.list_view.selectionModel().selectedIndexes() for index in selected_indexes: text = index.data(Qt.ItemDataRole.DisplayRole) print(f"选中项:{text}") # 获取当前选中的单个索引 current_index = self.list_view.currentIndex() if current_index.isValid(): print("当前选中:", current_index.data())

3. 操作数据模型

# 添加项(QStandardItemModel) new_item = QStandardItem("新项") self.model.appendRow(new_item) # 修改项 index = self.model.index(0, 0) # 第0行第0列 self.model.setData(index, "修改后的文本", Qt.ItemDataRole.DisplayRole) # 删除项 self.model.removeRow(0) # 删除第0行 # 清空所有项 self.model.clear() # 排序 self.model.sort(0, Qt.SortOrder.AscendingOrder) # 第0列升序

五、自定义委托(Delegate)

通过自定义委托可以完全控制列表项的绘制和编辑,示例(自定义背景色和字体):

from PySide6.QtCore import QModelIndex, Qt from PySide6.QtWidgets import QStyledItemDelegate, QStyle from PySide6.QtGui import QPainter, QColor, QFont import sys from PySide6.QtCore import QStringListModel from PySide6.QtWidgets import QApplication, QListView, QVBoxLayout, QWidget class MainWindow(QWidget): def __init__(self): super().__init__() self.setWindowTitle("QListView 基础示例") self.resize(400, 300) # 1. 创建布局 layout = QVBoxLayout(self) # 2. 创建 QListView self.list_view = QListView() layout.addWidget(self.list_view) # 3. 创建数据模型(QStringListModel 仅支持字符串) self.model = QStringListModel() # 设置初始数据 self.model.setStringList(["Python", "PySide6", "QListView", "Model/View"]) # 4. 将模型绑定到 QListView self.list_view.setModel(self.model) # 5. 可选:设置交互属性 self.list_view.setEditTriggers(QListView.EditTrigger.DoubleClicked) # 双击编辑 self.list_view.setSelectionMode(QListView.SelectionMode.ExtendedSelection) # 多选 self.list_view.setSpacing(3) # 列表项间距 # 使用自定义委托 self.list_view.setItemDelegate(CustomDelegate()) # 自定义委托 class CustomDelegate(QStyledItemDelegate): def paint(self, painter: QPainter, option, index: QModelIndex): """绘制列表项""" # 选中状态 if option.state & QStyle.StateFlag.State_Selected: painter.fillRect(option.rect, QColor(66, 133, 244)) # 蓝色背景 painter.setPen(QColor(255, 255, 255)) # 白色文字 else: # 交替行背景 if index.row() % 2 == 0: painter.fillRect(option.rect, QColor(240, 240, 240)) painter.setPen(QColor(0, 0, 0)) # 设置字体 font = QFont() font.setBold(True) painter.setFont(font) # 绘制文本 text = index.data(Qt.ItemDataRole.DisplayRole) painter.drawText(option.rect, Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignLeft, text) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())

六、实现鼠标右键

from PySide6.QtCore import QModelIndex, Qt, QPoint from PySide6.QtWidgets import QStyledItemDelegate, QStyle, QMenu from PySide6.QtGui import QPainter, QColor, QFont, QStandardItem, QStandardItemModel import sys from PySide6.QtCore import QStringListModel from PySide6.QtWidgets import QApplication, QListView, QVBoxLayout, QWidget class MainWindow(QWidget): def __init__(self): super().__init__() self.setWindowTitle("QListView 基础示例") self.resize(400, 300) # 1. 创建布局 layout = QVBoxLayout(self) # 2. 创建 QListView self.list_view = QListView() layout.addWidget(self.list_view) # 3. 创建数据模型(QStringListModel 仅支持字符串) self.model = QStandardItemModel() # 设置初始数据 # self.model.setStringList(["Python", "PySide6", "QListView", "Model/View"]) str_list = ["Python", "PySide6", "QListView", "Model/View"] for s in str_list: item = QStandardItem(s) self.model.appendRow(item) # 4. 将模型绑定到 QListView self.list_view.setModel(self.model) from PySide6.QtWidgets import QMenu # 绑定右键菜单 self.list_view.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.list_view.customContextMenuRequested.connect(self.show_context_menu) def show_context_menu(self, pos: QPoint): """显示右键菜单""" menu = QMenu() # 获取当前点击的项 index = self.list_view.indexAt(pos) if index.isValid(): menu.addAction("删除", lambda: self.model.removeRow(index.row())) menu.addAction("编辑", lambda: self.list_view.edit(index)) menu.addAction("添加项", lambda: self.model.appendRow(QStandardItem("新项"))) menu.exec(self.list_view.mapToGlobal(pos)) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())

七、海量数据优化

  • 使用 QAbstractItemModel 自定义模型,实现懒加载(仅加载可视区域数据);
  • 禁用不必要的特性(如自动排序、实时更新);
  • 使用 setUniformItemSizes(True) 优化布局计算:
self.list_view.setUniformItemSizes(True) # 所有项大小相同时启用,提升性能

注:仅当列表中所有项的尺寸完全一致时启用(如纯文本列表、统一图标 + 文本的项);若项尺寸不同(如部分项带长文本、部分带大图标),启用后会导致尺寸显示异常。

八、QListView vs QListWidget

特性

QListView

QListWidget

架构

Model/View 解耦

封装 Model 的便捷控件

数据量

适合海量数据(性能优)

适合少量数据(简单)

定制性

高(可自定义 Model/Delegate)

低(仅支持基础定制)

复杂度

稍高(需手动管理 Model)

低(开箱即用)

选型建议

  • 简单字符串列表、少量数据 → QListWidget;
  • 大量数据、自定义展示、多源数据复用 → QListView + 自定义 Model。

总结

QListView 是 PySide6 中功能强大的列表展示控件,核心在于 Model/View 架构的解耦设计。掌握其与QStringListModel/QStandardItemModel的配合、选择模式、信号绑定和自定义委托,可满足从简单列表到复杂自定义展示的各类需求。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/6 3:45:28

英雄联盟终极自动化神器:LeagueAkari 快速上手指南

还在为繁琐的游戏准备流程烦恼吗?英雄联盟自动化工具LeagueAkari帮你解放双手,让游戏体验更加丝滑流畅!这款基于官方LCU API开发的游戏辅助工具,完全免费且安全可靠,助你轻松实现从英雄选择到游戏流程的全方位自动化。…

作者头像 李华
网站建设 2026/6/5 16:21:38

League Akari完整指南:快速掌握英雄联盟终极自动化工具

League Akari完整指南:快速掌握英雄联盟终极自动化工具 【免费下载链接】LeagueAkari ✨兴趣使然的,功能全面的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/LeagueAkari 想要提升…

作者头像 李华
网站建设 2026/6/6 6:47:39

DownKyi专业指南:解锁B站视频下载全攻略

DownKyi专业指南:解锁B站视频下载全攻略 【免费下载链接】downkyi 哔哩下载姬downkyi,哔哩哔哩网站视频下载工具,支持批量下载,支持8K、HDR、杜比视界,提供工具箱(音视频提取、去水印等)。 项…

作者头像 李华
网站建设 2026/6/9 16:20:01

NVIDIA Profile Inspector显卡优化全攻略:深度性能调优指南

NVIDIA Profile Inspector显卡优化全攻略:深度性能调优指南 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector NVIDIA Profile Inspector(简称NPI)是一款能够深入NVIDIA…

作者头像 李华
网站建设 2026/6/9 17:43:48

深度学习实战(基于pytroch)系列完整目录

创作不易,本系列手把手从零基础开始动手深度学习实战。欢迎订阅专栏,有任何代码问题随时沟通。 本系列目录链接 深度学习实战(基于pytroch)系列(一)环境准备 深度学习实战(基于pytroch)系列(二)数学基础 深度学习实战(基于pytroch)系列(三)数据操作 深度学习实战…

作者头像 李华
网站建设 2026/6/9 17:41:02

Vibe Coding - Claude Code 做 Java 项目 AI 结对编程最佳实践

文章目录 概述一、Claude Code Developer Kit 是什么1. Claude Code:类 IDE 的 AI 开发伴侣2. Developer Kit:给 Claude 装上一整套 Java 技能包 二、快速上手:把 Developer Kit 装进你的 Java 项目1. 安装到本机 / CLI 环境2. 安装到具体的…

作者头像 李华