Python 带有setWordWrap(True)的QLabel在放置到QListWidget中时不会垂直调整大小,即使resizeMode已设置为调整

Python 带有setWordWrap(True)的QLabel在放置到QListWidget中时不会垂直调整大小,即使resizeMode已设置为调整,python,pyqt,pyqt5,qlabel,qlistwidget,Python,Pyqt,Pyqt5,Qlabel,Qlistwidget,如何将QLabels与setWordWrap(True)一起放入QListWidget/QListView中,以便在调整父窗口小部件的大小时正确调整QLabels的大小? 当我尝试这样做时,我遇到了QLabel没有获得正确高度的问题(请参见下面的示例2) 我正在使用 Python:3.8.5 PyQt5:5.15.2 示例1:使用QVBoxLayout 为了展示我想要实现的目标,我想首先展示一个示例,在这个示例中,我只需将QLabels添加到QVBoxLayout中 这正如我所希望的:如果我

如何将
QLabel
s与
setWordWrap(True)
一起放入
QListWidget
/
QListView
中,以便在调整父窗口小部件的大小时正确调整
QLabel
s的大小?

当我尝试这样做时,我遇到了QLabel没有获得正确高度的问题(请参见下面的示例2)

我正在使用

  • Python:3.8.5
  • PyQt5:5.15.2
示例1:使用
QVBoxLayout
为了展示我想要实现的目标,我想首先展示一个示例,在这个示例中,我只需将
QLabel
s添加到QVBoxLayout中

这正如我所希望的:如果我水平调整(主)窗口的大小,带有包装文本的
QLabel
将在垂直方向上占用更多空间

示例2:使用
QListWidget
这就是我遇到问题的代码:运行此代码不会为带有包装文本的
Qlabel
s提供任何额外空间

QListWidget
已在示例中使用,而不是
QListView
,但从我所看到的以及从我对这些类的理解来看,应该没有区别)

请注意,已将设置为
QListView.Adjust

但这没用

使用
QLabel
中的
sizeHint
设置QListWidgetItem的大小提示 如果在
\uuuu init\uuuu
中完成:

lwi\u item\u 2.setSizeHint(item\u widget\u 2\u qlabel.sizeHint())

问题是,它只需设置一次大小提示,然后sizeHint就会被卡住,因此带有包装文本的QLabel无法垂直展开或收缩

或者,使用此代码,以便在调整主窗口大小时更新sizeHint:

class MainWindow(QMainWindow):
    [...]

def resizeEvent(self, a0: QResizeEvent) -> None:
    super().resizeEvent(a0)
    row = 0
    while row < self.list_widget.count():
        lwi_item = self.list_widget.item(row)
        item_widget = self.list_widget.itemWidget(lwi_item)
        widget_size_hint = item_widget.sizeHint()
        lwi_item.setSizeHint(widget_size_hint)  # <--------
        row += 1
class主窗口(QMainWindow):
[...]
def resizeEvent(自身,a0:QResizeEvent)->无:
super().resizeEvent(a0)
行=0
而行lwi_item.setSizeHint(widget_size_hint)#在写这个问题时,我能够在
QListWidget
子类的重写
resizeEvent
中使用
QLabel.heightForWidth
找到解决方案

但这并不是我所希望的(我曾希望我错过了一些简单的东西,这样解决方案会更优雅)如果有人有比这更好的解决方案,请分享

无论如何,这是我用来让它工作的代码

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class ListWidget(QListWidget):
    def __init__(self):
        super().__init__()
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        """
        self.list_widget.setResizeMode(QListView.Adjust)
        -this is not needed with this solution. (Maybe because it only effects QListWidgetItems?)
        """

    def resizeEvent(self, a0: QResizeEvent) -> None:
        super().resizeEvent(a0)
        row = 0
        while row < self.count():
            lwi_item = self.item(row)
            item_widget = self.itemWidget(lwi_item)
            if isinstance(item_widget, QLabel) and hasattr(item_widget, "wordWrap") and item_widget.wordWrap():
                width_int = self.width() - self.contentsMargins().left() - self.contentsMargins().right()
                height_hfw_int = item_widget.heightForWidth(width_int)  # <--------
                widget_size_hint = QSize(width_int, height_hfw_int)
                lwi_item.setSizeHint(widget_size_hint)
            row += 1


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.list_widget = ListWidget()
        self.setCentralWidget(self.list_widget)

        lwi_item_1 = QListWidgetItem(self.list_widget)
        self.list_widget.addItem(lwi_item_1)
        item_1_widget_qlabel = QLabel("Item number 1")
        item_1_widget_qlabel.setStyleSheet("*{background-color: #f0f000;}")
        self.list_widget.setItemWidget(lwi_item_1, item_1_widget_qlabel)

        lwi_item_2 = QListWidgetItem(self.list_widget)
        self.list_widget.addItem(lwi_item_2)
        item_2_html_rich_str = "<span style='font-size:12pt'>Listen, strange women lyin in ponds distributin swords is no basis for a system of government.</span><br><span>Supreme executive power derives from a mandate from the masses, not from some farcical aquatic ceremony.</span>"
        item_2_markdown_str = "## Listen, strange women lyin in ponds distributin swords is no basis for a system of government.\n\nSupreme executive power derives from a mandate from the masses, not from some farcical aquatic ceremony."
        item_2_text_str = "Listen, strange women lyin in ponds distributin swords is no basis for a system of government.\n\nSupreme executive power derives from a mandate from the masses, not from some farcical aquatic ceremony."
        item_widget_2_qlabel = QLabel(item_2_html_rich_str)
        item_widget_2_qlabel.setTextFormat(Qt.RichText)  # Qt.RichText, Qt.MarkdownText, Qt.PlainText
        item_widget_2_qlabel.setWordWrap(True)  # <-------
        item_widget_2_qlabel.setStyleSheet("*{background-color: #00f0f0;}")
        self.list_widget.setItemWidget(lwi_item_2, item_widget_2_qlabel)


app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
app.exec_()
导入系统 从PyQt5.QtCore导入* 从PyQt5.QtGui导入* 从PyQt5.QtWidgets导入* 类ListWidget(QListWidget): 定义初始化(自): super()。\uuuu init\uuuuu() self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) """ self.list_widget.setResizeMode(QListView.Adjust) -此解决方案不需要这样做。(可能是因为它只影响QListWidgetItems?) """ def resizeEvent(自身,a0:QResizeEvent)->无: super().resizeEvent(a0) 行=0 而行height_hfw_int=item_widget.heightForWidth(width_int)#在写这个问题时,我能够在
QListWidget
子类的重写
resizeEvent
内部找到一个解决方案

但这并不是我所希望的(我曾希望我错过了一些简单的东西,这样解决方案会更优雅)如果有人有比这更好的解决方案,请分享

无论如何,这是我用来让它工作的代码

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class ListWidget(QListWidget):
    def __init__(self):
        super().__init__()
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        """
        self.list_widget.setResizeMode(QListView.Adjust)
        -this is not needed with this solution. (Maybe because it only effects QListWidgetItems?)
        """

    def resizeEvent(self, a0: QResizeEvent) -> None:
        super().resizeEvent(a0)
        row = 0
        while row < self.count():
            lwi_item = self.item(row)
            item_widget = self.itemWidget(lwi_item)
            if isinstance(item_widget, QLabel) and hasattr(item_widget, "wordWrap") and item_widget.wordWrap():
                width_int = self.width() - self.contentsMargins().left() - self.contentsMargins().right()
                height_hfw_int = item_widget.heightForWidth(width_int)  # <--------
                widget_size_hint = QSize(width_int, height_hfw_int)
                lwi_item.setSizeHint(widget_size_hint)
            row += 1


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.list_widget = ListWidget()
        self.setCentralWidget(self.list_widget)

        lwi_item_1 = QListWidgetItem(self.list_widget)
        self.list_widget.addItem(lwi_item_1)
        item_1_widget_qlabel = QLabel("Item number 1")
        item_1_widget_qlabel.setStyleSheet("*{background-color: #f0f000;}")
        self.list_widget.setItemWidget(lwi_item_1, item_1_widget_qlabel)

        lwi_item_2 = QListWidgetItem(self.list_widget)
        self.list_widget.addItem(lwi_item_2)
        item_2_html_rich_str = "<span style='font-size:12pt'>Listen, strange women lyin in ponds distributin swords is no basis for a system of government.</span><br><span>Supreme executive power derives from a mandate from the masses, not from some farcical aquatic ceremony.</span>"
        item_2_markdown_str = "## Listen, strange women lyin in ponds distributin swords is no basis for a system of government.\n\nSupreme executive power derives from a mandate from the masses, not from some farcical aquatic ceremony."
        item_2_text_str = "Listen, strange women lyin in ponds distributin swords is no basis for a system of government.\n\nSupreme executive power derives from a mandate from the masses, not from some farcical aquatic ceremony."
        item_widget_2_qlabel = QLabel(item_2_html_rich_str)
        item_widget_2_qlabel.setTextFormat(Qt.RichText)  # Qt.RichText, Qt.MarkdownText, Qt.PlainText
        item_widget_2_qlabel.setWordWrap(True)  # <-------
        item_widget_2_qlabel.setStyleSheet("*{background-color: #00f0f0;}")
        self.list_widget.setItemWidget(lwi_item_2, item_widget_2_qlabel)


app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
app.exec_()
导入系统 从PyQt5.QtCore导入* 从PyQt5.QtGui导入* 从PyQt5.QtWidgets导入* 类ListWidget(QListWidget): 定义初始化(自): super()。\uuuu init\uuuuu() self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) """ self.list_widget.setResizeMode(QListView.Adjust) -此解决方案不需要这样做。(可能是因为它只影响QListWidgetItems?) """ def resizeEvent(自身,a0:QResizeEvent)->无: super().resizeEvent(a0) 行=0 而行height_hfw_int=item_widget.heightForWidth(width_int)#为什么需要使用QListWidget和QLabels?@musicamante您好,谢谢您的提问。我在几个项目中使用了
QListWidget
/
QListView
,我想把
QLabel
放在那里的一个典型原因是因为我有一个自定义行/项小部件(使用
setItemWidget
添加)包含两个或三个其他小部件,其中之一是一个
QLabel
,其中包含我想要包装的文本——我愿意使用其他方法,因此如果您知道好的替代方法,请与我们分享!好吧,QLabel有点奇怪,因为它是唯一有自己处理大小方法的小部件,因为它的本质是能够根据可用空间调整其内容(部分情况下,反之亦然)。根据您所描述的,我可以理解这种方法的必要性,以及您在回答中提出的解决方案,请参阅
class MainWindow(QMainWindow):
    [...]

def resizeEvent(self, a0: QResizeEvent) -> None:
    super().resizeEvent(a0)
    row = 0
    while row < self.list_widget.count():
        lwi_item = self.list_widget.item(row)
        item_widget = self.list_widget.itemWidget(lwi_item)
        widget_size_hint = item_widget.sizeHint()
        lwi_item.setSizeHint(widget_size_hint)  # <--------
        row += 1
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class ListWidget(QListWidget):
    def __init__(self):
        super().__init__()
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        """
        self.list_widget.setResizeMode(QListView.Adjust)
        -this is not needed with this solution. (Maybe because it only effects QListWidgetItems?)
        """

    def resizeEvent(self, a0: QResizeEvent) -> None:
        super().resizeEvent(a0)
        row = 0
        while row < self.count():
            lwi_item = self.item(row)
            item_widget = self.itemWidget(lwi_item)
            if isinstance(item_widget, QLabel) and hasattr(item_widget, "wordWrap") and item_widget.wordWrap():
                width_int = self.width() - self.contentsMargins().left() - self.contentsMargins().right()
                height_hfw_int = item_widget.heightForWidth(width_int)  # <--------
                widget_size_hint = QSize(width_int, height_hfw_int)
                lwi_item.setSizeHint(widget_size_hint)
            row += 1


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.list_widget = ListWidget()
        self.setCentralWidget(self.list_widget)

        lwi_item_1 = QListWidgetItem(self.list_widget)
        self.list_widget.addItem(lwi_item_1)
        item_1_widget_qlabel = QLabel("Item number 1")
        item_1_widget_qlabel.setStyleSheet("*{background-color: #f0f000;}")
        self.list_widget.setItemWidget(lwi_item_1, item_1_widget_qlabel)

        lwi_item_2 = QListWidgetItem(self.list_widget)
        self.list_widget.addItem(lwi_item_2)
        item_2_html_rich_str = "<span style='font-size:12pt'>Listen, strange women lyin in ponds distributin swords is no basis for a system of government.</span><br><span>Supreme executive power derives from a mandate from the masses, not from some farcical aquatic ceremony.</span>"
        item_2_markdown_str = "## Listen, strange women lyin in ponds distributin swords is no basis for a system of government.\n\nSupreme executive power derives from a mandate from the masses, not from some farcical aquatic ceremony."
        item_2_text_str = "Listen, strange women lyin in ponds distributin swords is no basis for a system of government.\n\nSupreme executive power derives from a mandate from the masses, not from some farcical aquatic ceremony."
        item_widget_2_qlabel = QLabel(item_2_html_rich_str)
        item_widget_2_qlabel.setTextFormat(Qt.RichText)  # Qt.RichText, Qt.MarkdownText, Qt.PlainText
        item_widget_2_qlabel.setWordWrap(True)  # <-------
        item_widget_2_qlabel.setStyleSheet("*{background-color: #00f0f0;}")
        self.list_widget.setItemWidget(lwi_item_2, item_widget_2_qlabel)


app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
app.exec_()