3

I stumbled upon this (it is, obviously, an extract from a bigger application):

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'

If you run this, on the last line you get:

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

As far as I can tell any Qt object can be used as dict keys, just like any user-defined class instances.

I'm running PySide2 5.13.0, Python 3.6.4 on Windows 7. I get the same error on Ubuntu 18.04, Python 3.6.9, PySide 5.9.0a1.

Thanks for any hint.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
user6369958
  • 357
  • 3
  • 16
  • I don't think it's a bug, it seems that you expecting QListWidgetItem to be hashhable but it seems that it wasn't designed for that. Why do you need a QListWidgetItem to be the key of a dictionary? – eyllanesc Jan 11 '20 at 14:59
  • Because I want to associate informations to a set of QListWidgetItem in a dictionary, and easily retrieve these informations when I get a specific QListWidgetItem through a slot o via QListView.currentItem(). I already do this with QPushButtons and a lot of other Qt objects. – user6369958 Jan 11 '20 at 15:15
  • You are applying a pythonic solution to a framework that does not use the bases of python design so many python solutions will not work in Qt, Qt is a library that can work by itself, so it has alternatives for what you want as I propose in my answer . – eyllanesc Jan 11 '20 at 15:28

1 Answers1

5

QListWidgetItem (similar to QTableWidgetItem and QTreeWidgetItem) is not hashtable since a QListWidgetItem associated with a row can change without notification unlike QObjects such as QWidget, QPushButton, etc.

If your goal is to associate information with a QListWidgetItem then you can use the setData() and data() methods.

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_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241