微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

带有自定义小部件的 QListWidget

如何解决带有自定义小部件的 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 举报,一经查实,本站将立刻删除。