介绍
QListWidget 是 PySide2 中用于展示列表项的便捷控件,它是一种自包含的列表组件(内部集成了模型和视图),适合快速实现简单的列表功能。相比 QListView(需要手动关联模型),QListWidget 更简单易用,适合展示文本、图标等基础内容。
QListWidget 是简化版的列表控件,适合快速实现基础列表功能(如添加、删除、选择项),无需关注模型细节。如果需要更复杂的定制(如自定义项样式、复杂数据结构),则推荐使用 QListView 配合自定义模型。
核心特点
- 自带数据模型,无需手动创建
QStandardItemModel - 支持添加
QListWidgetItem类型的列表项 - 内置常用功能(如添加、删除、排序、多选选等)
- 适合快速开发简单列表(如文件列表、选项列表等)
基本用法示例
以下是 QListWidget 的常用操作(添加项、删除项、获取选中项等):
import sys
from PySide2.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout,
QListWidget, QListWidgetItem, QPushButton,
QLineEdit, QLabel, QMessageBox)
from PySide2.QtCore import Qt
from PySide2.QtGui import QIcon
class ListWidgetDemo(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QListWidget 示例")
self.setGeometry(300, 300, 500, 400)
# 1. 创建 QListWidget 控件
self.list_widget = QListWidget()
# 设置列表属性
self.list_widget.setSelectionMode(QListWidget.ExtendedSelection) # 支持多选
self.list_widget.setAlternatingRowColors(True) # 交替行颜色
self.list_widget.setSortingEnabled(True) # 启用排序(点击表头可排序)
# 2. 添加示例项
self.init_items()
# 3. 控制按钮区域
# 添加项输入框
add_layout = QHBoxLayout()
self.item_input = QLineEdit()
self.item_input.setPlaceholderText("输入要添加的项...")
add_btn = QPushButton("添加项")
add_btn.clicked.connect(self.add_item)
add_layout.addWidget(self.item_input)
add_layout.addWidget(add_btn)
# 操作按钮
btn_layout = QHBoxLayout()
del_btn = QPushButton("删除选中项")
del_btn.clicked.connect(self.delete_selected)
clear_btn = QPushButton("清空列表")
clear_btn.clicked.connect(self.list_widget.clear)
show_btn = QPushButton("显示选中项")
show_btn.clicked.connect(self.show_selected)
btn_layout.addWidget(del_btn)
btn_layout.addWidget(clear_btn)
btn_layout.addWidget(show_btn)
# 4. 组装布局
main_layout = QVBoxLayout()
main_layout.addWidget(QLabel("列表内容:"))
main_layout.addWidget(self.list_widget)
main_layout.addLayout(add_layout)
main_layout.addLayout(btn_layout)
self.setLayout(main_layout)
self.show()
def init_items(self):
"""初始化列表项(支持文本、图标、隐藏数据)"""
# 示例1:纯文本项
QListWidgetItem("项目 1", self.list_widget)
QListWidgetItem("项目 2", self.list_widget)
# 示例2:带图标项(实际使用时替换为真实图标路径)
icon_item = QListWidgetItem("带图标项", self.list_widget)
# icon_item.setIcon(QIcon("path/to/icon.png")) # 设置图标
# 示例3:带隐藏数据的项(使用 setData 存储)
hidden_data_item = QListWidgetItem("带隐藏数据", self.list_widget)
hidden_data_item.setData(Qt.UserRole + 1, {"id": 1001, "desc": "这是隐藏数据"})
def add_item(self):
"""添加新项到列表"""
text = self.item_input.text().strip()
if text:
# 添加新项到列表末尾
QListWidgetItem(text, self.list_widget)
self.item_input.clear()
else:
QMessageBox.warning(self, "警告", "请输入内容!")
def delete_selected(self):
"""删除选中的项"""
# 获取所有选中的项
selected_items = self.list_widget.selectedItems()
if not selected_items:
QMessageBox.information(self, "提示", "请先选中项!")
return
# 从列表中移除选中项
for item in selected_items:
row = self.list_widget.row(item) # 获取项的行索引
self.list_widget.takeItem(row) # 移除项(不销毁对象)
def show_selected(self):
"""显示选中项的信息(包括隐藏数据)"""
selected_items = self.list_widget.selectedItems()
if not selected_items:
QMessageBox.information(self, "提示", "请先选中项!")
return
info = ""
for i, item in enumerate(selected_items, 1):
# 获取显示文本
text = item.text()
# 获取隐藏数据(通过自定义角色)
hidden_data = item.data(Qt.UserRole + 1)
info += f"选中项 {i}:{text}\n"
if hidden_data:
info += f" 隐藏数据:{hidden_data}\n"
QMessageBox.information(self, "选中项信息", info)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = ListWidgetDemo()
sys.exit(app.exec_())
关键用法解析
1. 基本操作
- 创建列表:直接实例化
QListWidget即可,无需单独创建模型。 - 添加项:使用
QListWidgetItem(text, list_widget)创建项并添加到列表,或通过list_widget.addItem(item)手动添加。 - 删除项:通过
takeItem(row)移除指定行的项(row可通过row(item)获取)。 - 清空列表:调用
clear()方法快速清空所有项。
2. 选择模式
通过 setSelectionMode() 设置选择行为:
QListWidget.SingleSelection:单选(默认)QListWidget.ExtendedSelection:按住Ctrl或Shift多选QListWidget.MultiSelection:直接点击多选QListWidget.NoSelection:禁止选择
3. 存储隐藏数据
与 QListView 类似,QListWidgetItem 支持通过 setData() 存储不显示的数据:
item = QListWidgetItem("显示文本", self.list_widget)
# 用自定义角色存储隐藏数据(如ID、字典等)
item.setData(Qt.UserRole + 1, {"id": 1001, "status": "active"})
# 获取隐藏数据
hidden_data = item.data(Qt.UserRole + 1)
设置选中
在 PySide2 中,QListWidget 提供了多种方法设置选中项,可根据需求选择直接选中单个项、多个项或按条件选中。以下是常用的实现方式及示例:
import sys
from PySide2.QtWidgets import (QApplication, QWidget, QVBoxLayout,
QListWidget, QListWidgetItem, QPushButton,
QHBoxLayout, QLabel)
from PySide2.QtCore import Qt
class ListWidgetSelectionDemo(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QListWidget 设置选中项示例")
self.setGeometry(300, 300, 500, 400)
# 创建布局
main_layout = QVBoxLayout()
btn_layout = QHBoxLayout()
# 创建QListWidget并添加项
self.list_widget = QListWidget()
self.list_widget.setSelectionMode(QListWidget.ExtendedSelection) # 支持多选
self.items = ["项目1", "项目2", "项目3", "项目4", "项目5", "项目6"]
for text in self.items:
self.list_widget.addItem(text)
# 创建操作按钮
self.btn_select_first = QPushButton("选中第一项")
self.btn_select_last = QPushButton("选中最后一项")
self.btn_select_by_text = QPushButton("选中'项目3'")
self.btn_select_by_index = QPushButton("选中索引2的项")
self.btn_select_all = QPushButton("全选")
self.btn_deselect_all = QPushButton("取消全选")
self.btn_select_even = QPushButton("选中偶数项")
# 绑定按钮事件
self.btn_select_first.clicked.connect(self.select_first)
self.btn_select_last.clicked.connect(self.select_last)
self.btn_select_by_text.clicked.connect(self.select_by_text)
self.btn_select_by_index.clicked.connect(self.select_by_index)
self.btn_select_all.clicked.connect(self.list_widget.selectAll)
self.btn_deselect_all.clicked.connect(self.list_widget.clearSelection)
self.btn_select_even.clicked.connect(self.select_even_items)
# 添加控件到布局
btn_layout.addWidget(self.btn_select_first)
btn_layout.addWidget(self.btn_select_last)
btn_layout.addWidget(self.btn_select_by_text)
btn_layout.addWidget(self.btn_select_by_index)
main_layout.addWidget(QLabel("列表项:"))
main_layout.addWidget(self.list_widget)
main_layout.addLayout(btn_layout)
main_layout.addWidget(self.btn_select_all)
main_layout.addWidget(self.btn_deselect_all)
main_layout.addWidget(self.btn_select_even)
self.setLayout(main_layout)
self.show()
# 方法1:选中第一项
def select_first(self):
if self.list_widget.count() > 0:
item = self.list_widget.item(0) # 获取第一项
item.setSelected(True) # 设置选中
self.list_widget.setCurrentItem(item) # 同步当前项
# 方法2:选中最后一项
def select_last(self):
count = self.list_widget.count()
if count > 0:
item = self.list_widget.item(count - 1) # 获取最后一项
item.setSelected(True)
# 方法3:按文本选中项
def select_by_text(self):
target_text = "项目3"
# 遍历所有项查找匹配文本
for i in range(self.list_widget.count()):
item = self.list_widget.item(i)
if item.text() == target_text:
item.setSelected(True)
break
# 方法4:按索引选中项
def select_by_index(self):
index = 2 # 第3项(索引从0开始)
if 0 <= index < self.list_widget.count():
# 通过索引获取项并选中
self.list_widget.item(index).setSelected(True)
# 或通过setCurrentRow直接选中行
# self.list_widget.setCurrentRow(index)
# 方法5:按条件选中(示例:选中偶数索引项)
def select_even_items(self):
# 先取消现有选中
self.list_widget.clearSelection()
# 选中偶数索引项(0, 2, 4...)
for i in range(0, self.list_widget.count(), 2):
self.list_widget.item(i).setSelected(True)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = ListWidgetSelectionDemo()
sys.exit(app.exec_())
基本选中方法
item.setSelected(True):通过列表项对象设置选中状态(最常用)
item = self.list_widget.item(0) # 获取索引0的项
item.setSelected(True) # 选中
item.setSelected(False) # 取消选中
setCurrentRow(index):通过行索引选中项(同时会设置为当前项)
self.list_widget.setCurrentRow(2) # 选中索引2的项
setCurrentItem(item):通过项对象设置为当前选中项
item = self.list_widget.item(1)
self.list_widget.setCurrentItem(item) # 选中该项
批量选中方法
全选:selectAll()
self.list_widget.selectAll() # 选中所有项(需开启多选模式)
取消全选:clearSelection()
self.list_widget.clearSelection() # 取消所有选中项
按条件选中:遍历项并设置 setSelected()
# 示例:选中包含"关键词"的项
for i in range(self.list_widget.count()):
item = self.list_widget.item(i)
if "关键词" in item.text():
item.setSelected(True)
选择模式设置
需先通过 setSelectionMode() 设置多选规则,否则部分批量选中方法无效:
# 常用选择模式
self.list_widget.setSelectionMode(QListWidget.SingleSelection) # 单选(默认)
self.list_widget.setSelectionMode(QListWidget.MultiSelection) # 多选(点击即选)
self.list_widget.setSelectionMode(QListWidget.ExtendedSelection) # 扩展多选(Ctrl/Shift辅助)
注意事项
- 单选模式下,新选中项会自动取消之前的选中项;
setCurrentRow()和setCurrentItem()不仅会选中项,还会将其设为“当前项”(带虚线边框);- 批量选中前最好用
clearSelection()清空现有选中状态,避免冲突。
通过上述方法,可灵活实现 QListWidget 中各种选中需求,从简单的单项选到复杂的条件批量选都能覆盖。
获取选中的项
在 PySide2 中,QListWidget 获取选中值的方法取决于选择模式(单选/多选),常用方式有以下几种:
例子
import sys
from PySide2.QtWidgets import (QApplication, QWidget, QVBoxLayout,
QListWidget, QListWidgetItem, QPushButton,
QLabel, QHBoxLayout)
from PySide2.QtCore import Qt
class ListWidgetGetSelected(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QListWidget 获取选中值")
self.setGeometry(300, 300, 500, 400)
# 主布局
main_layout = QVBoxLayout()
# 创建列表并设置为多选模式
self.list_widget = QListWidget()
self.list_widget.setSelectionMode(QListWidget.ExtendedSelection) # 支持Ctrl/Shift多选
# 添加示例项(同时存储隐藏数据)
items = [
{"text": "项目A", "data": {"id": 101, "desc": "类型A"}},
{"text": "项目B", "data": {"id": 102, "desc": "类型B"}},
{"text": "项目C", "data": {"id": 103, "desc": "类型C"}},
{"text": "项目D", "data": {"id": 104, "desc": "类型D"}},
{"text": "项目E", "data": {"id": 105, "desc": "类型E"}}
]
for item_data in items:
item = QListWidgetItem(item_data["text"])
# 存储隐藏数据(使用UserRole)
item.setData(Qt.UserRole, item_data["data"])
self.list_widget.addItem(item)
# 按钮区域
btn_layout = QHBoxLayout()
self.btn_get_single = QPushButton("获取当前选中项")
self.btn_get_multi = QPushButton("获取所有选中项")
self.btn_get_hidden = QPushButton("获取选中项隐藏数据")
# 绑定按钮事件
self.btn_get_single.clicked.connect(self.get_single_selected)
self.btn_get_multi.clicked.connect(self.get_multi_selected)
self.btn_get_hidden.clicked.connect(self.get_hidden_data)
# 结果显示标签
self.result_label = QLabel("选中项信息将显示在这里")
self.result_label.setStyleSheet("border: 1px solid #eee; padding: 8px;")
# 组装布局
btn_layout.addWidget(self.btn_get_single)
btn_layout.addWidget(self.btn_get_multi)
btn_layout.addWidget(self.btn_get_hidden)
main_layout.addWidget(QLabel("请选择列表项:"))
main_layout.addWidget(self.list_widget)
main_layout.addLayout(btn_layout)
main_layout.addWidget(QLabel("结果:"))
main_layout.addWidget(self.result_label)
self.setLayout(main_layout)
self.show()
# 方法1:获取当前选中的单个项(适合单选模式)
def get_single_selected(self):
# 获取当前选中项(当前项指带虚线边框的项)
current_item = self.list_widget.currentItem()
if current_item:
self.result_label.setText(f"当前选中项:{current_item.text()}")
else:
self.result_label.setText("未选中任何项")
# 方法2:获取所有选中项(适合多选模式)
def get_multi_selected(self):
# 获取所有选中的项
selected_items = self.list_widget.selectedItems()
if not selected_items:
self.result_label.setText("未选中任何项")
return
# 提取选中项的文本
selected_texts = [item.text() for item in selected_items]
self.result_label.setText(
f"共选中 {len(selected_texts)} 项:\n" +
"\n".join(selected_texts)
)
# 方法3:获取选中项的隐藏数据(如ID、额外属性)
def get_hidden_data(self):
selected_items = self.list_widget.selectedItems()
if not selected_items:
self.result_label.setText("未选中任何项")
return
# 提取隐藏数据(通过UserRole)
hidden_info = []
for item in selected_items:
data = item.data(Qt.UserRole) # 获取存储的隐藏数据
hidden_info.append(
f"{item.text()} - ID: {data['id']}, 描述: {data['desc']}"
)
self.result_label.setText(
f"选中项隐藏数据:\n" +
"\n".join(hidden_info)
)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = ListWidgetGetSelected()
sys.exit(app.exec_())
获取单个选中项(适合单选模式)
currentItem():返回当前获得焦点的项(带虚线边框的项)
current_item = self.list_widget.currentItem()
if current_item:
text = current_item.text() # 获取显示文本
currentRow():返回当前选中项的索引,再通过索引获取项
row = self.list_widget.currentRow()
if row != -1: # -1表示无选中项
item = self.list_widget.item(row)
text = item.text()
获取所有选中项(适合多选模式)
selectedItems():返回所有选中项的列表(QListWidgetItem 对象集合)
selected_items = self.list_widget.selectedItems()
# 提取文本列表
selected_texts = [item.text() for item in selected_items]
获取选中项的隐藏数据
如果项中存储了隐藏数据(通过 setData() 方法),可通过 data() 提取:
# 假设用 Qt.UserRole 存储了隐藏数据
for item in self.list_widget.selectedItems():
hidden_data = item.data(Qt.UserRole) # 获取隐藏数据
print(f"文本: {item.text()}, 隐藏数据: {hidden_data}")
注意事项
选择模式影响结果:
- 单选模式(
SingleSelection)下,selectedItems()始终返回长度为 0 或 1 的列表 - 多选模式(
MultiSelection/ExtendedSelection)下,返回所有选中项
- 单选模式(
空值判断:操作前需判断是否有选中项(
currentItem()可能返回None,selectedItems()可能返回空列表)性能考虑:对于大量选中项(上千项),遍历
selectedItems()时需注意效率
通过上述方法,可根据实际需求灵活获取 QListWidget 中的选中值,包括显示文本和隐藏数据。
事件
在 PySide2 中,QListWidget 的事件用法主要围绕两类核心场景:1. 利用其内置信号绑定槽函数(推荐,简单高效);2. 重写事件处理方法(适用于深度定制交互逻辑)。前者基于信号-槽机制,无需关注底层事件分发;后者需直接处理鼠标、键盘等原始事件,灵活性更高。
一、核心:信号-槽机制(推荐优先使用)
QListWidget 提供了大量封装好的信号,对应列表项的选中、点击、双击、删除等常见交互,直接绑定槽函数即可实现功能,无需手动解析事件。
1. 常用信号及说明
| 信号名 | 触发时机 | 关键参数说明 |
|---|---|---|
itemClicked(QListWidgetItem *) |
列表项被鼠标点击时 | 被点击的 QListWidgetItem 对象 |
itemDoubleClicked(QListWidgetItem *) |
列表项被双击时 | 被双击的 QListWidgetItem 对象 |
currentItemChanged(QListWidgetItem *, QListWidgetItem *) |
当前选中项变化时 | 新选中项、上一个选中项(均为对象) |
itemSelectionChanged() |
选中项集合变化时(如多选时勾选/取消勾选) | 无参数,需通过 selectedItems() 获取选中项 |
itemPressed(QListWidgetItem *) |
列表项被鼠标按下时(比 itemClicked 早) |
被按下的 QListWidgetItem 对象 |
itemDeleted(QListWidgetItem *) |
列表项被删除时 | 被删除的 QListWidgetItem 对象 |
2. 信号-槽完整示例
from PySide2.QtWidgets import (QApplication, QMainWindow, QListWidget,
QListWidgetItem, QLabel, QVBoxLayout, QWidget)
import sys
class ListWidgetSignalDemo(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QListWidget 信号-槽示例")
self.setGeometry(300, 300, 400, 300)
# 中心Widget和布局
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout(central_widget)
# 1. 创建QListWidget并添加项
self.list_widget = QListWidget()
# 支持多选(可选,默认单选)
self.list_widget.setSelectionMode(QListWidget.MultiSelection)
# 添加测试项
items = ["项目1", "项目2", "项目3", "项目4", "项目5"]
for item_text in items:
# 可给项附加隐藏数据(通过setData存储,data读取)
item = QListWidgetItem(item_text)
item.setData(Qt.UserRole, f"隐藏数据_{item_text}") # 自定义角色存储额外信息
self.list_widget.addItem(item)
# 2. 显示交互信息的标签
self.info_label = QLabel("请操作列表项(点击、双击、切换选中)")
# 3. 绑定信号与槽函数
self.list_widget.itemClicked.connect(self.on_item_clicked)
self.list_widget.itemDoubleClicked.connect(self.on_item_double_clicked)
self.list_widget.currentItemChanged.connect(self.on_current_item_changed)
self.list_widget.itemSelectionChanged.connect(self.on_selection_changed)
# 添加控件到布局
layout.addWidget(self.list_widget)
layout.addWidget(self.info_label)
# ------------------------------
# 槽函数实现
# ------------------------------
def on_item_clicked(self, item: QListWidgetItem):
"""处理列表项点击事件"""
text = item.text()
hidden_data = item.data(Qt.UserRole) # 读取隐藏数据
self.info_label.setText(f"点击项: {text} | 隐藏数据: {hidden_data}")
def on_item_double_clicked(self, item: QListWidgetItem):
"""处理列表项双击事件(示例:删除双击项)"""
text = item.text()
self.list_widget.takeItem(self.list_widget.row(item)) # 删除项
self.info_label.setText(f"双击删除项: {text}")
def on_current_item_changed(self, new_item: QListWidgetItem, old_item: QListWidgetItem):
"""处理选中项变化事件"""
if new_item: # 避免初始无选中项时的None
self.info_label.setText(f"切换选中项: 从 {old_item.text() if old_item else '无'} 到 {new_item.text()}")
def on_selection_changed(self):
"""处理多选时的选中集合变化"""
selected_items = self.list_widget.selectedItems() # 获取所有选中项
selected_texts = [item.text() for item in selected_items]
self.info_label.setText(f"当前选中项: {', '.join(selected_texts)}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = ListWidgetSignalDemo()
window.show()
sys.exit(app.exec_())
二、进阶:重写事件处理方法(深度定制)
当信号-槽无法满足需求(如自定义鼠标右键菜单、拦截特定键盘按键、处理拖拽事件等)时,可通过重写 QListWidget 的事件方法或安装事件过滤器实现。
1. 重写 QListWidget 自身的事件方法
直接继承 QListWidget,重写其 mousePressEvent、keyPressEvent 等方法,捕获原始事件。
示例:自定义右键菜单(重写鼠标按下事件)
from PySide2.QtWidgets import (QApplication, QMainWindow, QListWidget,
QListWidgetItem, QMenu, QAction)
from PySide2.QtCore import Qt
import sys
# 1. 继承QListWidget,重写事件方法
class CustomListWidget(QListWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.init_context_menu() # 初始化右键菜单
def init_context_menu(self):
"""创建右键菜单"""
self.context_menu = QMenu(self)
# 添加菜单动作
self.action_delete = QAction("删除选中项", self)
self.action_delete.triggered.connect(self.delete_selected_items)
self.action_clear = QAction("清空列表", self)
self.action_clear.triggered.connect(self.clear)
# 添加到菜单
self.context_menu.addAction(self.action_delete)
self.context_menu.addAction(self.action_clear)
def mousePressEvent(self, event):
"""重写鼠标按下事件:右键显示菜单"""
# 先调用父类方法,确保正常的选中逻辑(如左键点击选中项)
super().mousePressEvent(event)
# 若右键点击,且点击位置有项
if event.button() == Qt.RightButton:
# 获取右键点击位置对应的项
clicked_item = self.itemAt(event.pos())
if clicked_item: # 点击在项上
self.context_menu.exec_(event.globalPos()) # 显示菜单
def delete_selected_items(self):
"""删除选中项"""
for item in self.selectedItems():
self.takeItem(self.row(item))
# 2. 主窗口使用自定义ListWidget
class CustomEventDemo(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("QListWidget 重写事件示例")
self.setGeometry(300, 300, 400, 300)
# 使用自定义的ListWidget
self.custom_list = CustomListWidget()
# 添加测试项
for i in range(5):
self.custom_list.addItem(f"自定义项{i+1}")
self.setCentralWidget(self.custom_list)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = CustomEventDemo()
window.show()
sys.exit(app.exec_())
2. 安装事件过滤器(监控子控件或外部事件)
若不想修改 QListWidget 本身,可在其父控件上安装事件过滤器,监控 QListWidget 的所有事件(如拦截键盘按键)。
示例:拦截 “Delete” 键删除选中项
from PySide2.QtWidgets import (QApplication, QMainWindow, QListWidget,
QListWidgetItem)
from PySide2.QtCore import QEvent, Qt
import sys
class EventFilterDemo(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QListWidget 事件过滤器示例")
self.setGeometry(300, 300, 400, 300)
self.list_widget = QListWidget()
for i in range(5):
self.list_widget.addItem(f"过滤事件项{i+1}")
self.setCentralWidget(self.list_widget)
# 给list_widget安装事件过滤器(监控者是当前主窗口)
self.list_widget.installEventFilter(self)
def eventFilter(self, watched, event):
"""重写事件过滤器:watched是被监控的对象,event是事件"""
# 仅处理list_widget的事件
if watched == self.list_widget:
# 拦截键盘按键事件
if event.type() == QEvent.KeyPress:
key = event.key()
if key == Qt.Key_Delete: # 按下Delete键
# 删除选中项
for item in self.list_widget.selectedItems():
self.list_widget.takeItem(self.list_widget.row(item))
return True # 返回True表示事件已处理,不再传递
# 其他事件交给默认处理
return super().eventFilter(watched, event)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = EventFilterDemo()
window.show()
sys.exit(app.exec_())
三、关键注意事项
- 信号-槽优先:绝大多数常规需求(点击、选中、双击)都可通过信号-槽实现,无需重写事件,代码更简洁易维护。
QListWidgetItem的隐藏数据:通过item.setData(Qt.UserRole, 数据)存储额外信息(如ID、路径),item.data(Qt.UserRole)读取,避免仅依赖显示文本。- 事件传递顺序:重写事件时,若需保留原有逻辑(如左键选中项),务必先调用
super().xxxEvent(event)。 - 多选模式:通过
setSelectionMode()设置(如QListWidget.MultiSelection支持多选),多选时用selectedItems()获取所有选中项。
总结
QListWidget 的事件用法分为「基础信号-槽」和「进阶事件重写/过滤」:
- 简单交互(点击、选中、删除)→ 用 信号-槽;
- 深度定制(右键菜单、拦截按键、拖拽)→ 用 重写事件方法 或 事件过滤器。
两者结合可覆盖几乎所有列表交互场景。