Search code examples
pythonpython-3.xpyqtpyqt5qlistwidget

how to add a QListWidgetItem on top of the QListWidget?


I am trying to create something like a layer editor that you normally see in most of the image editor softwares, and for this I need to add the new layers on the top of the QListWidget, the code that I'm currently trying is this one:

def new_layer(self):

    layer = Layer(layer_name="Layer %d" % self.number_of_layers)
    layer_item = QListWidgetItem(self)
    layer_item.setSizeHint(layer.sizeHint())

    if self.number_of_layers % 2 == 0:
        layer_item.setBackground(Qt.darkGray)
    else:
        layer_item.setBackground(Qt.gray)

    self.setItemWidget(layer_item, layer)
    self.insertItem(0, layer_item)

    self.number_of_layers += 1

even after inserting the QListWidgetItem in the row 0, when the new layer is added it is displayed beneath the first layer that was previously created. What could I do to fix it?


Solution

  • According to the docs:

    QListWidgetItem::QListWidgetItem(QListWidget * parent = 0, int type = Type)

    Constructs an empty list widget item of the specified type with the given parent. If parent is not specified, the item will need to be inserted into a list widget with QListWidget::insertItem().

    This constructor inserts the item into the model of the parent that is passed to the constructor. If the model is sorted then the behavior of the insert is undetermined since the model will call the '<' operator method on the item which, at this point, is not yet constructed. To avoid the undetermined behavior, we recommend not to specify the parent and use QListWidget::insertItem() instead.

    From the above it is concluded that you should not pass the parent to the QListWidgetItem, so your code should look like the following:

    def new_layer(self):
    
        layer = Layer(layer_name="Layer %d" % self.number_of_layers)
        layer_item = QListWidgetItem() #remove self
        layer_item.setSizeHint(layer.sizeHint())
    
        if self.number_of_layers % 2 == 0:
            layer_item.setBackground(Qt.darkGray)
        else:
            layer_item.setBackground(Qt.gray)
    
        self.insertItem(0, layer_item)
        self.setItemWidget(layer_item, layer)
    
    
        self.number_of_layers += 1