I have a QListWidget where I want to add a bunch of items with a custom widget:
listWidget = QListWidget()
item = QListWidgetItem()
item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
item.setCheckState(Qt.Unchecked)
listWidget.addItem(item)
widget = MyLabelAndPushButton()
item.setSizeHint(widget.sizeHint())
listWidget.setItemWidget(item, widget)
As the name suggests MyLabelAndPushButton is just a widget containing a QLabel and a QPushButton in a layout. The problem is that I can not use the checkbox that appears in the listwidget next to the widget. It looks completely normal, but nothing happens when I click on it. If I remove the line with setItemWidget it works correctly. What am I doing wrong?
edit:
Reported bug at bugreports.qt.io/browse/QTBUG-16386 but got the reply "API is not designed for what you intend to do" and "In case if you want to display custom widget, use QListView and subclass QItemDelegate." So apparently it's not a bug, just something the API can't handle.
I'm not sure why exactly list item doesn't want to change its state when widget is set. I guess the workaround for this issue would be either adding a check box in your widget or connect to the listwidget's itemClicked signal and reset item's state there. Pls, see if an example below would work for you:
import sys
from PyQt4 import QtGui, QtCore
class MainForm(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainForm, self).__init__(parent)
listWidget = QtGui.QListWidget()
item = QtGui.QListWidgetItem()
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
item.setCheckState(QtCore.Qt.Unchecked)
listWidget.addItem(item)
widget = QtGui.QCheckBox('test')
item.setSizeHint(widget.sizeHint())
listWidget.setItemWidget(item, widget)
listWidget.itemClicked.connect(self.on_listWidget_itemClicked)
self.setCentralWidget(listWidget)
def on_listWidget_itemClicked(self, item):
if item.listWidget().itemWidget(item) != None:
if item.checkState() == QtCore.Qt.Checked:
item.setCheckState(QtCore.Qt.Unchecked)
else:
item.setCheckState(QtCore.Qt.Checked)
def main():
app = QtGui.QApplication(sys.argv)
form = MainForm()
form.show()
app.exec_()
if __name__ == '__main__':
main()
hope this helps, regards
The docs for QListWidget::setItemWidget say:
This function should only be used to display static content in the place of a list widget item. If you want to display custom dynamic content or implement a custom editor widget, use QListView and subclass QItemDelegate instead.
By "static content" I suppose it means non-interactive, indicating that this is a known limitation when using QListWidget.
It is absolutely the same in C++, so not only a python / pyqt problem (played around with that for some time now to see if I can find a solution). I first thought this is the old bug with Qt::ItemIsEnabled coming back which we already had in 4.2, but it was not.
This is either working as intended and not enough described in the documentation (my +1 for this), or a bug.
To be sure about this, I would file a bug at https://bugreports.qt.io, and see what they say about this.
来源:https://stackoverflow.com/questions/4510341/cant-change-state-of-checkable-qlistviewitem-with-custom-widget