You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5:点击子部件按钮删除QListWidgetItem及字典引用

解决方案

首先要修正两个关键问题:给widgetItem传入并保存对应的itemID,以及正确移除QListWidgetItem的方式。

1. 修改widgetItem的初始化方法

需要把主程序中的itemID传入widgetItem,并保存父对象和自身的itemID:

class widgetItem(QtWidgets.QWidget):
    def __init__(self, parent, item_id):
        super(widgetItem, self).__init__()
        uic.loadUi('UIfiles/trainingWidget.ui', self) # Load the .ui file

        self.itemID = item_id  # 保存自身的itemID
        self.parent = parent  # 保存主窗口对象引用
        self.listWidgetItem = QtWidgets.QListWidgetItem()
        self.listWidgetItem.setSizeHint(self.sizeHint())
        self.delete.clicked.connect(self.deleteSelf)
        parent.listWidget.addItem(self.listWidgetItem)
        parent.listWidget.setItemWidget(self.listWidgetItem, self)

2. 修正主程序的additem方法

创建widgetItem时传入当前的itemID:

def additem(self):
    self.referenceDict[self.itemID] = widgetItem(self, self.itemID)  

3. 实现deleteSelf方法

按顺序完成移除列表项、删除字典引用、销毁自身三个步骤:

def deleteSelf(self):
    # 从listWidget中移除并销毁QListWidgetItem
    row = self.parent.listWidget.row(self.listWidgetItem)
    if row != -1:
        # takeItem会将item从列表中移除并返回,随后可以安全销毁
        item = self.parent.listWidget.takeItem(row)
        del item  # 或调用item.deleteLater(),效果一致
    
    # 从referenceDict中删除对应条目
    try:
        self.parent.referenceDict.pop(self.itemID)
    except KeyError:
        # 可选:键不存在时的处理,比如打印日志
        pass
    
    # 销毁当前QWidget部件
    self.deleteLater()

问题原因说明

  • 之前调用self.listWidgetItem.deleteLater()报错:因为QListWidget仍持有该item的引用,直接销毁会触发属性错误,必须先用takeItem从列表中移除后再处理。
  • 字典pop触发键错误:因为原代码中widgetItem没有保存正确的itemID,导致找不到对应键值对。
  • deleteLater只删了QWidget:QListWidgetItem和其绑定的QWidget是两个独立对象,需要分别处理移除和销毁。

内容的提问来源于stack exchange,提问作者ChronoVortex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 22:48:52