【发布时间】:2020-12-06 19:58:14
【问题描述】:
我正在尝试使用QStyledItemDelegate 和我的QListView 在项目中显示富文本。
第一次绘制项目时,它的高度太小。如果然后我将鼠标悬停在该项目上,它将以正确的高度重新绘制。以下是初始绘制和重绘的屏幕截图。
如何使初始绘制的高度正确?
演示问题的示例代码:
from PySide2 import QtCore, QtGui, QtWidgets
class RichTextItemDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self, parent=None):
super(RichTextItemDelegate, self).__init__(parent)
self.doc = QtGui.QTextDocument(self)
def paint(self, painter, option, index):
painter.save()
self.initStyleOption(option, index)
self.doc.setHtml(option.text)
option_no_text = QtWidgets.QStyleOptionViewItem(option)
option_no_text.text = ''
style = QtWidgets.QApplication.style() if option_no_text.widget is None else option_no_text.widget.style()
style.drawControl(QtWidgets.QStyle.CE_ItemViewItem, option_no_text, painter)
margin_top = (option.rect.height() - self.doc.size().height()) // 2
text_rect = style.subElementRect(QtWidgets.QStyle.SE_ItemViewItemText, option_no_text, None)
text_rect.setTop(text_rect.top() + margin_top)
painter.translate(text_rect.topLeft())
painter.setClipRect(text_rect.translated(-text_rect.topLeft()))
context = QtGui.QAbstractTextDocumentLayout.PaintContext()
self.doc.documentLayout().draw(painter, context)
painter.restore()
def sizeHint(self, option, index):
other = super().sizeHint(option, index)
w = min(self.doc.idealWidth(), other.width())
h = max(self.doc.size().height(), other.height())
return QtCore.QSize(w, h)
class ExampleWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
item = QtGui.QStandardItem()
item.setText('Example<br><span style="font-size: 14pt; font-weight: bold;">Example<br>Example<br>Example</span>', )
model = QtGui.QStandardItemModel()
model.appendRow(item)
self.listview = QtWidgets.QListView(parent=self)
self.listview.setModel(model)
delegate = RichTextItemDelegate(self.listview)
self.listview.setItemDelegate(delegate)
app = QtWidgets.QApplication([])
example = ExampleWidget()
example.resize(320, 240)
example.show()
app.exec_()
【问题讨论】:
-
我没有重现你的问题,你可以指出你的环境特征:python版本,pyside2版本,操作系统等
-
Windows 10、Python 3.7.6、PySide2 5.15.0。
-
我看到
sizeHint()在paint()被调用之前被调用了5 次......我只是不知道该怎么做。 -
mmm,好像是个bug,加
print(w, h)会得到什么?在设置模型之前尝试设置委托 -
移动
setItemDelegate无效。我看到一个调用序列,如:sizeHint: 8.0, 24.0; paint; sizeHint: 107.0, 108.0;。因为self.doc.setHtml直到paint才会被调用,我认为这就是我所期望的。我想知道如何在调用paint 之前设置文档文本。
标签: python pyside2 qstyleditemdelegate