news 2026/3/12 1:57:28

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/3/11 8:36:22

PySide6之QListWidget 学习

QListWidget 是 PySide6 中封装了数据模型的便捷列表控件(基于 Model/View 架构,但内置了 QListWidgetItem 数据项,无需手动创建模型),适用于快速实现简单列表、少量数据展示的场景,相比 QListView 更易上手…

作者头像 李华
网站建设 2026/3/8 19:46:48

BetterJoy终极配置指南:轻松实现Switch手柄的PC游戏革命

还在为Switch手柄无法在电脑上使用而烦恼吗?BetterJoy为你打开了一扇全新的大门!这款强大的工具能够让任天堂Switch Pro控制器、Joy-Con手柄以及SNES控制器完美兼容CEMU、Citra、Dolphin、Yuzu等主流模拟器,更可以作为通用XInput设备在PC游戏…

作者头像 李华
网站建设 2026/3/3 17:13:07

NVIDIA Profile Inspector性能优化完全手册:解锁显卡隐藏潜力

NVIDIA Profile Inspector性能优化完全手册:解锁显卡隐藏潜力 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 还在为游戏画面卡顿、撕裂而烦恼?想要充分发挥显卡的全部性能却无从…

作者头像 李华
网站建设 2026/3/11 23:47:49

英雄联盟智能革命:LeagueAkari自动化助手如何重塑你的游戏体验

英雄联盟智能革命:LeagueAkari自动化助手如何重塑你的游戏体验 【免费下载链接】LeagueAkari ✨兴趣使然的,功能全面的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/LeagueAkari …

作者头像 李华
网站建设 2026/2/20 17:03:25

AngularJS 实例详解

AngularJS 实例详解 概述 AngularJS 是一个流行的前端JavaScript框架,由Google维护,用于构建动态和复杂的前端应用。本文将通过具体实例,详细介绍AngularJS的基本用法,帮助读者快速掌握其核心概念和应用技巧。 实例一:AngularJS 模板语法 1.1 简介 AngularJS 使用双大…

作者头像 李华
网站建设 2026/3/11 22:29:03

Kotlin 对象表达式/声明

Kotlin 对象表达式/声明 引言 Kotlin 是一种现代化的编程语言,它旨在提高开发效率并减少样板代码。在 Kotlin 中,对象表达式和声明是两种强大的特性,它们允许开发者以简洁、灵活的方式创建对象。本文将深入探讨 Kotlin 对象表达式和声明的概念、用法及其在实践中的应用。 …

作者头像 李华