Here is a picture of my GUI:
I want to display all 100 items in my list widget without an inner scroll bar (there is an outer scroll bar, so there is no issue that I cannot fit all the items).
I have tried disabling the scroll bar for the list widget, but that didn't increase the number of items the list widget was displaying.
Here is my code:
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys
if __name__ == "__main__":
app = QApplication(sys.argv)
dlg = QDialog()
listWidget = QListWidget()
for i in range(100):
listWidget.addItem(QListWidgetItem("Item " + str(i)))
layout1 = QVBoxLayout()
layout1.addWidget(QLabel("Label 1"))
groupBox1 = QGroupBox("Group 1")
groupBox1.setLayout(layout1)
layout2 = QVBoxLayout()
layout2.addWidget(listWidget)
groupBox2 = QGroupBox("Group 2")
groupBox2.setLayout(layout2)
nestedWidgetLayout = QVBoxLayout()
nestedWidgetLayout.addWidget(groupBox1)
nestedWidgetLayout.addWidget(groupBox2)
nestedWidget = QWidget()
nestedWidget.setLayout(nestedWidgetLayout)
scrollArea = QScrollArea()
scrollArea.setWidget(nestedWidget)
mainLayout = QVBoxLayout()
mainLayout.addWidget(scrollArea)
dlg.setLayout(mainLayout)
dlg.show()
app.exec()
The @a_manthey_67 solution gives us a starting point but has several limitations:
Considering the above, I have implemented a similar logic using sizeHintForRow()
, in addition to enabling the widgetResizable
property of the QScrollArea
and disabling the verticalScrollBar.
import sys
from PyQt5.QtCore import pyqtSlot, Qt
from PyQt5.QtWidgets import (
QApplication,
QDialog,
QGroupBox,
QLabel,
QListWidget,
QListWidgetItem,
QScrollArea,
QVBoxLayout,
QWidget,
)
class ListWidget(QListWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.model().rowsInserted.connect(self._recalcultate_height)
self.model().rowsRemoved.connect(self._recalcultate_height)
@pyqtSlot()
def _recalcultate_height(self):
h = sum([self.sizeHintForRow(i) for i in range(self.count())])
self.setFixedHeight(h)
if __name__ == "__main__":
app = QApplication(sys.argv)
dlg = QDialog()
listWidget = ListWidget()
for i in range(100):
listWidget.addItem(QListWidgetItem("Item " + str(i)))
layout1 = QVBoxLayout()
layout1.addWidget(QLabel("Label 1"))
groupBox1 = QGroupBox("Group 1")
groupBox1.setLayout(layout1)
layout2 = QVBoxLayout()
layout2.addWidget(listWidget)
groupBox2 = QGroupBox("Group 2")
groupBox2.setLayout(layout2)
nestedWidget = QWidget()
nestedWidgetLayout = QVBoxLayout(nestedWidget)
nestedWidgetLayout.addWidget(groupBox1)
nestedWidgetLayout.addWidget(groupBox2)
scrollArea = QScrollArea(widgetResizable=True)
scrollArea.setWidget(nestedWidget)
mainLayout = QVBoxLayout(dlg)
mainLayout.addWidget(scrollArea)
dlg.show()
sys.exit(app.exec_())