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

PySide2代码Python2运行正常Python3报unhashable type: 'ListWidgetItem'错误

错误产生原因

PySide2信号连接绑定实例方法时,内部会将槽函数所属的实例作为键存入字典,用于管理连接生命周期(比如实例销毁时自动断开连接),该操作需要对实例做哈希计算。

  • Python2环境下,自定义类如果没有显式定义__hash__方法,会默认使用实例的内存id作为哈希值,因此就算QListWidgetItem本身未实现哈希逻辑,也能正常运算不报错。
  • Python3环境规则不同:如果一个类显式实现了__eq__方法但未实现__hash__方法,__hash__会被自动设为None,实例变为不可哈希类型。QListWidgetItem的Qt绑定已经实现了__eq__用于项的相等判断,但未实现__hash__,因此在Python3中作为字典键时就会触发不可哈希的报错。
可行解决方案

以下三种方案均可解决该问题,按侵入性从低到高排序:


方案1:用lambda/partial包装槽函数

不需要修改原有类定义,仅修改信号连接逻辑,避免直接绑定实例方法触发哈希计算:

# 用lambda包装
widget.resized.connect(lambda width, height: item.resize_to_widget_size(width, height))

# 或者用functools.partial
from functools import partial
widget.resized.connect(partial(item.resize_to_widget_size))

方案2:给自定义ListWidgetItem类添加哈希方法

显式指定用实例内存id作为哈希值,符合唯一标识的需求:

class ListWidgetItem(QtWidgets.QListWidgetItem):
    def __init__(self):
        super(ListWidgetItem, self).__init__()
    
    # 新增__hash__方法
    def __hash__(self):
        return id(self)

    def resize_to_widget_size(self, width, height):
        self.setSizeHint(QtCore.QSize(width, height))

修改后原有的信号连接代码不需要改动即可正常运行。


方案3:将槽函数所属实例改为继承QObject的可哈希类型

如果有其他相关需求,可以把业务逻辑放到继承自QObject的类中实现,QObject的实例默认在Python3环境下可哈希,不过该方案改动量较大,适合重构场景使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 06:06:02