news 2026/4/18 0:35:56

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/4/17 13:00:35

Switch手柄电脑控制器终极配置指南:从基础连接到专业玩法

Switch手柄电脑控制器终极配置指南:从基础连接到专业玩法 【免费下载链接】BetterJoy Allows the Nintendo Switch Pro Controller, Joycons and SNES controller to be used with CEMU, Citra, Dolphin, Yuzu and as generic XInput 项目地址: https://gitcode.c…

作者头像 李华
网站建设 2026/4/18 3:46:31

XUnity自动翻译器:打破语言壁垒的智能汉化引擎

XUnity自动翻译器:打破语言壁垒的智能汉化引擎 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 在游戏全球化的今天,玩家们常常会遇到语言障碍的困扰。XUnity自动翻译器作为一款专为…

作者头像 李华
网站建设 2026/4/18 3:52:44

哔哩下载姬(DownKyi)快速入门与深度应用指南

哔哩下载姬(DownKyi)快速入门与深度应用指南 【免费下载链接】downkyi 哔哩下载姬downkyi,哔哩哔哩网站视频下载工具,支持批量下载,支持8K、HDR、杜比视界,提供工具箱(音视频提取、去水印等)。 项目地址:…

作者头像 李华
网站建设 2026/4/17 13:12:05

Go 语言接口

Go 语言接口 引言 Go 语言,又称为 Golang,是一种静态强类型、编译型、并发型、具有垃圾回收功能的编程语言。它由 Google 的 Robert Griesemer、Rob Pike 和 Ken Thompson 设计,自 2009 年公开以来,因其简洁、高效、易于理解等优点,在国内外获得了广泛的应用。本文将详细…

作者头像 李华
网站建设 2026/4/17 20:50:02

舵机角度测量

简 介: 舵机旋转角度特性分析 摘要:本文研究了舵机旋转角度与控制信号PWM高电平时间的关系。实验通过可编程信号发生器产生控制信号,测量结果显示舵机输出角度在0.408ms-2.537ms的高电平范围内呈近似线性变化,角度变化范围约283。…

作者头像 李华
网站建设 2026/4/18 3:44:21

终极DLSS升级指南:3步实现游戏画质飞跃

终极DLSS升级指南:3步实现游戏画质飞跃 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper 想要快速提升游戏画质?通过DLSS版本替换,你可以在不升级硬件的情况下获得更清晰的图像和更流畅…

作者头像 李华