当前位置: 首页 > news >正文

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的配合、选择模式、信号绑定和自定义委托,可满足从简单列表到复杂自定义展示的各类需求。

http://www.jsqmd.com/news/188913/

相关文章:

  • GitHub汉化插件完整指南:3分钟实现全界面中文
  • BetterJoy终极配置指南:轻松实现Switch手柄的PC游戏革命
  • 游戏汉化终极指南:XUnity翻译器完全使用手册
  • TranslucentTB完整指南:3步实现Windows任务栏透明美化
  • C++11 STL常用算法
  • League Akari完整指南:快速掌握英雄联盟终极自动化工具
  • 英雄联盟智能助手League Akari:3分钟掌握高效游戏新姿势
  • LeagueAkari英雄联盟助手:新手必备的完整使用教程
  • XUnity自动翻译器:Unity游戏本地化解决方案详解
  • 强烈安利10个AI论文平台,专科生轻松搞定毕业论文!
  • NVIDIA Profile Inspector终极教程:快速掌握显卡性能优化秘诀
  • 英雄联盟终极自动化神器:LeagueAkari 快速上手指南
  • NVIDIA Profile Inspector深度解析:如何快速掌握显卡性能调优的完整指南
  • MAA明日方舟智能辅助工具:高效自动化解决方案全面解析
  • XUnity自动翻译器终极指南:5分钟实现游戏汉化零障碍
  • leetcode 846. Hand of Straights 一手顺子-耗时97%
  • WPF Prism.Wpf, Prsim.DryIOC integrate sub module/project into main module via IRegionManager
  • DownKyi专业指南:解锁B站视频下载全攻略
  • XUnity自动翻译器:5步轻松实现游戏汉化的终极指南
  • LeagueAkari英雄联盟智能助手使用完全指南
  • 英雄联盟终极免费自动化助手:LeagueAkari完整使用指南
  • 成为三剑客很难,手持两股剑倒有可能
  • DownKyi智能视频下载工具实战指南:3种高效方法深度解析
  • 英雄联盟智能助手:5个实用功能让你游戏体验大升级
  • 2026年北京朝阳海淀装修公司权威推荐TOP5:别墅定制与老房改造优选指南(首推品牌:北京亿丰方圆装饰) - 品牌智鉴榜
  • XUnity自动翻译器:3步解锁外语游戏中文版,告别语言障碍困扰
  • NVIDIA Profile Inspector显卡优化全攻略:深度性能调优指南
  • 浅学 AES 算法
  • LeagueAkari:英雄联盟智能助手终极使用指南
  • 基于PSO粒子群优化的VMD-GRU时间序列预测算法matlab仿真