18

I am trying to make a QListWidget in which each item is a simple widget that contains text and a pushbutton. I use the following:

itemN = QtGui.QListWidgetItem() 
#Create widget
widget = QtGui.QWidget()
widgetText =  QtGui.QLabel("I love PyQt!")
widgetButton =  QtGui.QPushButton("Push Me")
widgetLayout = QtGui.QHBoxLayout()
widgetLayout.addWidget(widgetText)
widgetLayout.addWidget(widgetButton)
widgetLayout.addStretch()
widget.setLayout(widgetLayout)
#Add widget to QListWidget funList
funList.addItem(itemN)
funList.setItemWidget(itemN, widget)

The problem is, nothing shows up. I get a blank line that I can navigate using my keyboard, but it is blank. When the widget contains just a pushbutton, it works, so it isn't as if the pushbutton alone is messing things up. Are there limits on the complexity of widgets that setItemWidget can handle? Perhaps I need to go beyond the convenience classes, as suggested in some of the related posts below?

Related posts

pyqt adding a widget to a QListWidget
Note the previous post has a similar title to mine, but seems to be a relatively poorly expressed question about a complex pastiche of code from QtDesigner (mixed with some custom stuff). It is not clear at all that this is actually the question the person should have been asking. While the title makes it seem like a duplicate, the question (I pray) is not.

I would say something similar about this post.

QListWidgetItem with Radio Button

QListView/QListWidget with custom items and custom item widgets

Adding Custom Widget to QListWidget in QT click issue in QT?

pyqt adding a widget to a QListWidget

http://www.qtcentre.org/threads/8660-Drawing-a-widget-in-QItemDelegate-s-paint-method

http://developer.nokia.com/community/discussion/showthread.php/211634-Adding-a-button-inside-QListWidgetItem

Community
  • 1
  • 1
eric
  • 7,142
  • 12
  • 72
  • 138

2 Answers2

31

Try this:

itemN = QtGui.QListWidgetItem() 
#Create widget
widget = QtGui.QWidget()
widgetText =  QtGui.QLabel("I love PyQt!")
widgetButton =  QtGui.QPushButton("Push Me")
widgetLayout = QtGui.QHBoxLayout()
widgetLayout.addWidget(widgetText)
widgetLayout.addWidget(widgetButton)
widgetLayout.addStretch()

widgetLayout.setSizeConstraint(QtGui.QLayout.SetFixedSize)
widget.setLayout(widgetLayout)  
itemN.setSizeHint(widget.sizeHint())    

#Add widget to QListWidget funList
funList.addItem(itemN)
funList.setItemWidget(itemN, widget)

As you can see, you need setSizeConstraint to the layout and setSizeHint to item.

eric
  • 7,142
  • 12
  • 72
  • 138
Jablonski
  • 18,083
  • 2
  • 46
  • 47
  • that works! It isn't super clear to me what's happening. 1) Once the size constraint is set, do I truly need to `setSizeHint` to the item too? It _seems_ leaving out `setSizeHint` doesn't change the appearance of my GUI. 2) Why did my size hint default to -1, -1 in the first place, and how does using 'SetFixedSize' fix this? Why doesn't it just fix it at the wrong value (-1, -1). Any good docs going over the ins-and-outs of these issues? (Docs include: http://qt-project.org/doc/qt-4.8/qt.html#SizeHint-enum and http://qt-project.org/doc/qt-4.8/qlayout.html#SizeConstraint-enum) – eric Oct 05 '14 at 14:35
  • 2
    @neuronet `QLayout::SetFixedSize` The main widget's size is set to `sizeHint();` it cannot be resized at all. If you will not set size hint, your widget with label and button will be bigger then item, so it will be extremely ugly and uncorrect. – Jablonski Oct 05 '14 at 14:43
  • 1
    Accepting answer because it solved problem, but will definitely upvote anyone who explains the ins-and-outs of this, to bring next person beyond cargo cult programming :) – eric Oct 05 '14 at 17:28
7

If you use PyQt5, there is some changes, you must use QtWidgets for widget not QtGui. Use this code if using with PyQt5:

Don't forget to import PyQt5:

from PyQt5 import QtCore, QtGui, QtWidgets`

itemN = QtWidgets.QListWidgetItem()
# Create widget
widget = QtWidgets.QWidget()
widgetText = QtWidgets.QLabel("I love PyQt!")
widgetButton = QtWidgets.QPushButton("Push Me")
widgetLayout = QtWidgets.QHBoxLayout()
widgetLayout.addWidget(widgetText)
widgetLayout.addWidget(widgetButton)
widgetLayout.addStretch()

widgetLayout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
widget.setLayout(widgetLayout)
itemN.setSizeHint(widget.sizeHint())

# Add widget to QListWidget funList
funList.addItem(itemN)
funList.setItemWidget(itemN, widget)

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
ALFAFA
  • 598
  • 3
  • 7
  • Cute, but it there a way to have these widget filled QListWidgetItems not turn out to be absolute chonkers? They're just too tall with wasted space. – snaxxus Sep 24 '20 at 17:18
  • 1
    @user1469620 try it: `widgetLayout.setContentsMargins(0, 0, 0, 0)` – S. Nick Sep 24 '20 at 18:48