QListWidget 显示更多项目
QListWidget display more items
这是我的 GUI 的图片:
我想在没有内部滚动条的情况下显示我的列表小部件中的所有 100 个项目(有一个外部滚动条,所以不存在我无法容纳所有项目的问题)。
我试过禁用列表小部件的滚动条,但这并没有增加列表小部件显示的项目数。
这是我的代码:
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()
如果 listwidget 的高度大于所有项目的高度,则所有项目都显示在 listWidget 中,但没有滚动条(listWidget 的)。在此片段中,项目的高度由 item.sizeHint()
设置,并且计算出的 listwidget 所需高度比所有项目所需的高度大 10 像素。 sizeHint()
需要 QSize
作为参数。
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
@a_manthey_67 解决方案为我们提供了一个起点,但有几个限制:
- 它是针对特定数量的项目计算的,因此如果项目是 added/deleted,它将失败。
- 手动设置每个项目的高度,而不是获取样式设置的高度。
考虑到上述情况,除了启用 QScrollArea
的 widgetResizable
属性 并禁用 verticalScrollBar 之外,我还使用 sizeHintForRow()
实现了类似的逻辑。
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_())
这是我的 GUI 的图片:
我想在没有内部滚动条的情况下显示我的列表小部件中的所有 100 个项目(有一个外部滚动条,所以不存在我无法容纳所有项目的问题)。
我试过禁用列表小部件的滚动条,但这并没有增加列表小部件显示的项目数。
这是我的代码:
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()
如果 listwidget 的高度大于所有项目的高度,则所有项目都显示在 listWidget 中,但没有滚动条(listWidget 的)。在此片段中,项目的高度由 item.sizeHint()
设置,并且计算出的 listwidget 所需高度比所有项目所需的高度大 10 像素。 sizeHint()
需要 QSize
作为参数。
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
@a_manthey_67 解决方案为我们提供了一个起点,但有几个限制:
- 它是针对特定数量的项目计算的,因此如果项目是 added/deleted,它将失败。
- 手动设置每个项目的高度,而不是获取样式设置的高度。
考虑到上述情况,除了启用 QScrollArea
的 widgetResizable
属性 并禁用 verticalScrollBar 之外,我还使用 sizeHintForRow()
实现了类似的逻辑。
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_())