QListWidgetItem 对象是不可散列的,这是一个错误还是有原因?

Posted

技术标签:

【中文标题】QListWidgetItem 对象是不可散列的,这是一个错误还是有原因?【英文标题】:QListWidgetItem objects are unhashable, it is a bug or there's a reason? 【发布时间】:2020-01-11 10:28:04 【问题描述】:

我偶然发现了这个(显然,它是从更大的应用程序中提取的):

import sys
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *

if __name__ == '__main__':

    app = QApplication(sys.argv)

    d = 

    widget = QWidget()
    d[widget] = 'hashable'

    item = QListWidgetItem('abc')
    d[item] = 'unhashable'

如果你运行这个,在最后一行你会得到:

TypeError: unhashable type: 'PySide2.QtWidgets.QListWidgetItem'

据我所知,任何 Qt 对象都可以用作字典键,就像任何用户定义的类实例一样。

我在 Windows 7 上运行 PySide2 5.13.0、Python 3.6.4。我在 Ubuntu 18.04、Python 3.6.9、PySide 5.9.0a1 上遇到同样的错误。

感谢任何提示。

【问题讨论】:

我不认为这是一个错误,您似乎希望 QListWidgetItem 是可散列的,但它似乎不是为此而设计的。为什么需要 QListWidgetItem 作为字典的键? 因为我想将信息与字典中的一组 QListWidgetItem 相关联,并且当我通过插槽 o 通过 QListView.currentItem() 获取特定 QListWidgetItem 时轻松检索这些信息。我已经用 QPushButtons 和许多其他 Qt 对象做到了这一点。 您正在将pythonic解决方案应用于不使用python设计基础的框架,因此许多python解决方案在Qt中不起作用,Qt是一个可以自己工作的库,所以它有替代方案正如我在回答中提出的那样,您想要什么。 【参考方案1】:

QListWidgetItem(类似于 QTableWidgetItem 和 QTreeWidgetItem)不是哈希表,因为与行关联的 QListWidgetItem 可以在没有通知的情况下更改,这与 QObject、QPushButton 等 QObject 不同。

如果您的目标是将信息与 QListWidgetItem 相关联,那么您可以使用 setData()data() 方法。

import sys

from PySide2.QtCore import Qt
from PySide2.QtWidgets import QApplication, QListWidget, QListWidgetItem, QWidget

if __name__ == "__main__":

    app = QApplication(sys.argv)

    w = QListWidget()

    for i in range(10):
        it = QListWidgetItem("abc-".format(i))
        it.setData(Qt.UserRole, "data-".format(i))
        w.addItem(it)

    def on_currentItemChanged():
        current = w.currentItem()
        print(current.data(Qt.UserRole))

    w.currentItemChanged.connect(on_currentItemChanged)
    w.show()
    sys.exit(app.exec_())

【讨论】:

以上是关于QListWidgetItem 对象是不可散列的,这是一个错误还是有原因?的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:使用一组 UDT 创建 Cassandra Python 驱动程序模型时不可散列的类型 UserType

nltk 的朴素基分类器给出不可散列的类型错误

多标签计算类权重 - 不可散列的类型

TypeError:张量是不可散列的。相反,使用 tensor.ref() 作为键。在 Keras 外科医生

Python - 重复数据删除问题:TypeError:不可散列的类型:'numpy.ndarray'

不可散列的类型:加入 PySpark RDD 时的“列表”