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_())
if the height of listwidget is bigger than the height of all all items all items are shown in listWidget but no scrollbar (of listWidget). in this snippet height of items is set by item.sizeHint()
and the needed height of listwidget calculated 10 px bigger than needed for all items. sizeHint()
needs QSize
as parameter.
listWidget = QListWidget()
lineHeight = 20
items = 100
for i in range(items):
item = QListWidgetItem("Item " + str(i)) # get every item to set sizeHint()
item.setSizeHint(QSize(-1, lineHeight)) # -1 = width undefined
listWidget.addItem(item)
listWidget.setFixedHeight(items*lineHeight + 10) # set fixed height of listwidget
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.