pythonpyqtqlistwidgetqlistwidgetitemrecursionerror

Getting current item QListWidget on ItemSelectedChanged()


I get the error: "RecursionError: maximum recursion depth exceeded while calling a Python object"

Snippet:

        def makeLabel():
            item = listWidget.currentItem() #RecursionError: maximum recursion depth exceeded while calling a Python object
            rect = listWidget.visualItemRect(item)
            itemPos = QPoint(rect.x(), rect.y())
            imageSize = item.icon().actualSize(QSize(100, 200))

            listWidget.takeItem(listWidget.currentRow())

            label = MovableLabel(self, 'Pogba.jpg')
            pixmap = item.icon().pixmap(imageSize)
            label.setPixmap(pixmap)
            label.setFixedSize(imageSize)
            label.move(itemPos)
            label.grabMouse()
            label.oldPos = itemPos
            label.clicked = False
            label.show()

        self.players = []
        pixmap = QPixmap()

        listWidget = QListWidget(self)
        listWidget.setViewMode(QListWidget.IconMode)
        listWidget.setFixedSize(500, 700)
        listWidget.setIconSize(QSize(100, 200))
        listWidget.setDragDropMode(listWidget.InternalMove)
        listWidget.setFocusPolicy(Qt.NoFocus) #Why no work?
        listWidget.itemSelectionChanged.connect(makeLabel)
        self.listWidget = listWidget

Why am I getting this error?


Solution

  • The issue is due to the fact that the selection changes also when an item is removed, so it creates a recursion:

    1. select an item
    2. the signal is emitted and...
    3. the function is called
    4. the function removes the item
    5. the previously selected item doesn't exist any more, so Qt tries to select a new item instead
    6. the selection is changed, the signal is emitted again
    7. go back to 3 (thus, recursion)

    Removing items within a selection change is a bad idea, and should never be done.

    A possible solution could be to disconnect the signal before removing the item, but it's not a good solution and I highly discourage you to do that; in this case, the objective is to try to do something similar to drag&drop, which should not be done like this, for two important reasons:

    1. drag operations should always use mouse events (usually mouseMoveEvent, but there are situations for which mouseButtonPress is also possible), not selections;
    2. Qt provides a strong and reliable support for drag and drop, and any other attempt to implement those operations in different ways is considered bad practice, as most of the times results in unexpected behavior, bugs or crashes (like in this case);