QListWidgetItem的内容调整

2024-04-24 22:58:57 发布

您现在位置:Python中文网/ 问答频道 /正文

当用户将对话框的大小调整为列表项的比例时,我如何才能做到这一点。目前他们似乎没有这样做。。。它们的大小与工具发布时相同。我已经启用了自动换行。我该如何解决这个问题

当我缩放宽度时,它看起来很好,如图所示

enter image description here

但当我放大它时,它看起来是错误的

enter image description here

import os
import sys
import re
import random

from PySide2 import QtGui, QtWidgets, QtCore

class ListWidgetItem(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(ListWidgetItem, self).__init__(parent)
        self.setStyleSheet('background: green;')

        self.uiTitle = QtWidgets.QLabel()
        self.uiTitle.setWordWrap(True)
        self.uiTitle.setText('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc porta ornare odio sit amet suscipit. Curabitur orci urna, commodo quis urna ut, consequat sodales urna.')

        self.subtitle = QtWidgets.QLabel()
        self.subtitle.setText('Title')

        undoicon = self.style().standardIcon(QtWidgets.QStyle.SP_BrowserReload)
        self.button = QtWidgets.QPushButton('Click Me')
        self.button.setIcon(undoicon)

        self.mainLayout = QtWidgets.QVBoxLayout()
        self.mainLayout.setAlignment(QtCore.Qt.AlignTop)
        self.mainLayout.setSpacing(0)
        self.mainLayout.addWidget(self.subtitle)
        self.mainLayout.addWidget(self.uiTitle)
        self.mainLayout.addWidget(self.button)
        self.setLayout(self.mainLayout)

class ListWidget(QtWidgets.QListWidget):
    def __init__(self, parent=None):
        super(ListWidget, self).__init__(parent)
        self.resize(400,400)
        self.setSpacing(1)
        self.setSelectionMode(QtWidgets.QListView.ExtendedSelection)
        self.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
        self.verticalScrollBar().setSingleStep(10)
        self.setWordWrap(True)
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.setSizeAdjustPolicy(QtWidgets.QListWidget.AdjustToContents)
        self.populateItems()

    def appendListWidget(self, widget):
        lwi = QtWidgets.QListWidgetItem()
        lwi.setSizeHint(widget.sizeHint())
        self.addItem(lwi)
        self.setItemWidget(lwi, widget)

    def populateItems(self):
        for x in range(10):
            widget = ListWidgetItem()
            self.appendListWidget(widget)

def main():
    app = QtWidgets.QApplication(sys.argv)
    ex = ListWidget()
    ex.show()
    app.exec_()


if __name__ == '__main__':
    pass
    main()

1条回答
网友
1楼 · 发布于 2024-04-24 22:58:57

列表项的大小提示集是静态的,并且基于小部件的初始大小提示,因此它不会完全适应,特别是当内容可以更改其纵横比时。它将在需要时增加其尺寸,但不会收缩

问题来自单词包装,这是Qt布局的一个已知限制。从布局管理的Layout Issues部分:

The use of rich text in a label widget can introduce some problems to the layout of its parent widget. Problems occur due to the way rich text is handled by Qt's layout managers when the label is word wrapped.

一种可能的解决方案是覆盖列表小部件的resizeEvent,并通过考虑^{}来基于内容进行一些计算

这需要两个for循环(只需一个就可以稍微优化,但改进很小,因为在当前视口中不太可能看到这么多小部件)。
第一个循环是检查可见项是否适合当前视图而不显示滚动条,第二个循环是根据可用宽度为小部件实际设置新的大小提示

显然,如果您使用ScrollBarAlwaysOn策略,您只需要执行一个循环,考虑到滚动条提示从开始的宽度(不要使用实际的滚动条大小,因为它将在尚未显示视图时返回不同的值)

class ListWidget(QtWidgets.QListWidget):
    # ...
    def resizeEvent(self, event):
        super().resizeEvent(event)
        width = self.viewport().width() - self.frameWidth() * 2
        if width > self.minimumSizeHint().width():
            # ensure that we have enough horizontal space to display the 
            # contents by avoiding recursion of the resize event
            maxHeight = self.viewport().height()
            height = 0
            spacing = self.spacing()
            for i in range(self.count()):
                item = self.item(i)
                widget = self.itemWidget(item)
                if not widget:
                    continue
                height += widget.heightForWidth(width)
                if height > maxHeight:
                    # we can't fit all items in the current visible rect
                    width -= self.verticalScrollBar().sizeHint().width()
                    break
                height += spacing
        else:
            width = self.minimumSizeHint().width()
        for i in range(self.count()):
            item = self.item(i)
            widget = self.itemWidget(item)
            if widget:
                item.setSizeHint(
                    QtCore.QSize(width, widget.heightForWidth(width))
                )

相关问题 更多 >