Search code examples
pythonpyqt5qlistwidgetqlistwidgetitem

Inflate custom widget in ListWidget - PyQt5


I am trying to design a list of items each of which is a custom widget (not necessarily though, I want to display an image and three texts in each item). In PyQt, the function addItem can be used to add an item to the list that takes as argument QListWidgetItem.

As such, I was trying to cast my custom defined widget to QListWidetItem with no success. I tried the following chunk of code:

listWidget = QtWidgets.QListWidget(self.centralwidget)
item = QListWidgetItem(self.listWidget)
custom_item = CustomWidget()
listWidget.addItem(item)
listWidget.setItemWidget(item, item_widget)

The list displays an empty list, and this is expected since I am never inflating the custom_item with the above code. How to fix this in PyQT?

I am not sure, but the custom widget might be relevant:

class CustomWidget(QWidget):
    def __init__(self, user):
        QWidget.__init__(self)
        self.user = user
        self.horizontalLayoutWidget = QtWidgets.QWidget()
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 211, 41))
        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.UserImage = QtWidgets.QLabel(self.horizontalLayoutWidget)
        self.UserImage.setText("This is an Image")
        self.UserImage.setObjectName("UserImage")
        self.horizontalLayout.addWidget(self.UserImage)
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")
        self.UserName = QtWidgets.QLabel(self.horizontalLayoutWidget)
        self.UserName.setText("My name is jeff")
        self.UserName.setObjectName("UserName")
        self.verticalLayout.addWidget(self.UserName)
        self.UserStatus = QtWidgets.QLabel(self.horizontalLayoutWidget)
        self.UserStatus.setText("I am available")
        self.UserStatus.setObjectName("UserStatus")
        self.verticalLayout.addWidget(self.UserStatus)
        self.horizontalLayout.addLayout(self.verticalLayout)
        self.horizontalLayout.setStretch(0, 1)
        self.horizontalLayout.setStretch(1, 3)

Solution

  • What I notice from your code is that the widget is not built correctly, self.horizontalLayout is the main widget but it has no parent so it will never be drawn, besides that you can avoid that widget. On the other hand, you must set the size of the item with setSizeHint():

    from PyQt5 import QtWidgets, QtCore
    
    class CustomWidget(QtWidgets.QWidget):
        def __init__(self, user, *args, **kwargs):
            QtWidgets.QWidget.__init__(self, *args, **kwargs)
            self.user = user
            self.setGeometry(QtCore.QRect(0, 0, 211, 41))
            self.horizontalLayout = QtWidgets.QHBoxLayout(self)
            self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
            self.horizontalLayout.setObjectName("horizontalLayout")
            self.UserImage = QtWidgets.QLabel(self)
            self.UserImage.setText("This is an Image")
            self.UserImage.setObjectName("UserImage")
            self.horizontalLayout.addWidget(self.UserImage)
            self.verticalLayout = QtWidgets.QVBoxLayout()
            self.verticalLayout.setObjectName("verticalLayout")
            self.UserName = QtWidgets.QLabel(self)
            self.UserName.setText("My name is jeff")
            self.UserName.setObjectName("UserName")
            self.verticalLayout.addWidget(self.UserName)
            self.UserStatus = QtWidgets.QLabel(self)
            self.UserStatus.setText("I am available")
            self.UserStatus.setObjectName("UserStatus")
            self.verticalLayout.addWidget(self.UserStatus)
            self.horizontalLayout.addLayout(self.verticalLayout)
            self.horizontalLayout.setStretch(0, 1)
            self.horizontalLayout.setStretch(1, 3)
    
    
    if __name__ == '__main__':
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        listWidget = QtWidgets.QListWidget()
        item = QtWidgets.QListWidgetItem(listWidget)
        item_widget = CustomWidget("user")
        listWidget.addItem(item)
        listWidget.setItemWidget(item, item_widget)
        item.setSizeHint(item_widget.sizeHint())
        listWidget.show()
        sys.exit(app.exec_())
    

    enter image description here