I have a QListWidget
inside a QTreeWidget
and I want it to automatically adjust its height as rows are added or removed. I got the QListWidget
autosizing working but it breaks when it's inside the QTreeWidget
, the QListWidget
grows in size but the QTreeWidget
doesn't adjust to it properly and other rows get covered.
from PyQt5 import QtCore, QtGui, QtWidgets, sip
from PyQt5.QtCore import Qt
class MyListWidget(QtWidgets.QListWidget):
def sizeHint(self):
width = super().sizeHint().width()
height = sum([self.sizeHintForRow(i) for i in range(self.count())]) + 5
return QtCore.QSize(width, height)
app = QtWidgets.QApplication([])
tree = QtWidgets.QTreeWidget()
item1 = QtWidgets.QTreeWidgetItem(tree, ['item1'])
item2 = QtWidgets.QTreeWidgetItem(tree, ['item2'])
item3 = QtWidgets.QTreeWidgetItem(tree, ['item3'])
list_widget = MyListWidget()
list_widget.addItems(list('abcd'))
tree.setItemWidget(item1, 0, list_widget)
button = QtWidgets.QPushButton("Add row")
button.clicked.connect(lambda: [list_widget.addItem("New row"),
list_widget.adjustSize(),
tree.adjustSize(),
tree.updateGeometry()
])
container = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
container.setLayout(layout)
layout.addWidget(tree)
layout.addWidget(button)
container.show()
list_widget.show()
app.exec_()
Initial Output:
Output After clicking Add New:
As you can see in the second image, item2
is now covered by the expanded list widget, the desired output would be to shift the item2
, such that after adding new item inside the list widget doesn't cover the item below it in the same tree widget.
You can subclass the tree and connect the model's rowsInserted
and rowsRemoved
signals, then update geometries accordingly, including that of the item:
class TreeWidget(QtWidgets.QTreeWidget):
def setItemWidget(self, item, column, widget):
super().setItemWidget(item, column, widget)
if isinstance(widget, MyListWidget):
widget.model().rowsInserted.connect(
lambda: self.updateItemWidget(item, column))
widget.model().rowsRemoved.connect(
lambda: self.updateItemWidget(item, column))
def updateItemWidget(self, item, column):
widget = self.itemWidget(item, column)
item.setSizeHint(column, widget.sizeHint())
self.updateGeometries()