带有自定义小部件的 QListWidget

问题描述

我需要创建一个自定义绘制的消息列表。由于此问题 QStyledItemDelegate's option is not updating 中描述的原因,qstyledItemDelegate 失败后,我尝试使用 QListWidget。但是我不明白我应该如何更改其中小部件的大小。例如,我缩小了窗口的范围,因此小部件必须增加高度,但是我的自定义小部件的 sizeHint 函数在开始时只调用了两次,之后再也不调用了。这是我使用的最小可重现示例:

import sys
from PyQt5.QtCore import (
    Qt,QSize,QRect,QRectF,)
from PyQt5.QtGui import (
    QPainter,QFontMetrics,QFont,QTextDocument,QTextOption,QPen,)
from PyQt5.QtWidgets import (
    QApplication,QListView,QMainWindow,QListWidget,QListWidgetItem,QWidget,)

frame_width = 0

class MessageWidget(QWidget):

    def __init__(self,msg):
        super(MessageWidget,self).__init__()
        self.msg = msg
        self.font = QFont("Times",14)

    def paintEvent(self,event):
        field = QRect(0,self.width(),self.height())
        doc = QTextDocument(self.msg)
        doc.setDocumentMargin(0)
        opt = QTextOption()
        opt.setWrapMode(opt.WrapAtWordBoundaryOrAnywhere)
        doc.setDefaultTextOption(opt)
        doc.setDefaultFont(self.font)
        doc.setTextWidth(field.size().width())
        field.setHeight(int(doc.size().height()))
        field.setWidth(int(doc.idealWidth()))
        painter = QPainter(self)
        painter.setPen(Qt.gray)
        painter.setFont(self.font)
        painter.translate(field.x(),field.y())
        textrectf = QRectF(field)
        textrectf.moveto(0,0)
        doc.drawContents(painter,textrectf)
        painter.translate(-field.x(),-field.y())

    def sizeHint(self):
        print("Here")
        global frame_width
        doc = QTextDocument(self.msg)
        doc.setDocumentMargin(0)
        opt = QTextOption()
        opt.setWrapMode(opt.WrapAtWordBoundaryOrAnywhere)
        doc.setDefaultTextOption(opt)
        doc.setDefaultFont(self.font)
        doc.setTextWidth(frame_width)
        return QSize(0,int(doc.size().height()))


class Dialog(QMainWindow):

    def __init__(self):
        global frame_width
        super(Dialog,self).__init__()
        self.setMinimumSize(int(QApplication.primaryScreen().size().width() * 0.1),int(QApplication.primaryScreen().size().height() * 0.2))
        self.resize(int(QApplication.primaryScreen().size().width() * 0.3),int(QApplication.primaryScreen().size().height() * 0.5))
        self.messages = QListWidget()
        frame_width = self.messages.size().width()
        self.message_array = []
        self.message_array.append("qwerty qwerty qwerty qwerty qwerty qwerty qwerty qwerty qwerty qwerty qwerty qwerty qwerty qwerty")
        self.message_array.append("abcdef")
        for i in range(len(self.message_array)):
            item = QListWidgetItem()
            widget = MessageWidget(self.message_array[i])
            item.setSizeHint(widget.sizeHint())
            self.messages.addItem(item)
            self.messages.setItemWidget(item,widget)
        self.messages.setResizeMode(QListView.Adjust)
        self.setCentralWidget(self.messages)

    def resizeEvent(self,event):
        global frame_width
        super(Dialog,self).resizeEvent(event)
        frame_width = int(self.messages.size().width())

app = QApplication(sys.argv)
window = Dialog()
window.show()
app.exec_()

我不确定我在这里是否正确使用了项目和小部件,但正如我在本示例中所说的那样,“此处”(打印在 sizeHint 的开头)仅在程序启动时打印 4 次。然后无论我如何调整窗口大小,都不会调用 sizeHint,因此不会修改小部件的大小。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)