Python QListWidget与自定义小部件
我需要创建自定义绘制消息的列表。由于本问题中所述的原因,Python QListWidget与自定义小部件,python,qt,pyqt,pyqt5,qlistwidget,Python,Qt,Pyqt,Pyqt5,Qlistwidget,我需要创建自定义绘制消息的列表。由于本问题中所述的原因,QStyledItemDelegate失败后,我尝试使用QListWidget来实现此目的。然而,我不明白我应该如何改变其中小部件的大小。例如,我缩小了窗口,因此小部件必须增加高度,但我的自定义小部件的sizeHint函数在开始时只调用了两次,此后再也没有调用过。这是我使用的最小可重复性示例: import sys from PyQt5.QtCore import ( Qt, QSize, QRect, QR
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, 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_()
我不确定这里是否正确使用了项目和小部件,但正如我在本例中所说,“here”(在
sizeHint
开头打印)在程序启动时仅打印4次。然后,无论我如何调整窗口大小,都不会调用sizeHint
,因此不会修改小部件的大小。提示没有定义的行为(Qt甚至不承诺使用它),因为它是一个提示。甚至可以要求,也可以不要求。尝试明确指定小部件的大小。当父窗口小部件知道显式大小时,它可能也会请求提示。@AlexanderV我应该指定窗口小部件的大小还是项目的大小?我该怎么做呢?使用调整大小
方法?是的,弗拉德,确保有一个大小。通常,最小大小与提示一起使用。