我在QListWidget中有一个QTextEdit,我需要能够计算QTextEdit的高度,以便可以在列表中设置QListWidgetItem的大小提示。我想出了如何获得一条线的高度并将其乘以行数,但是QTextEdit.document().lineCount()
每次都会返回1
。我认为这是因为尚未设置文档的宽度,因此它还没有弄清楚如何拆分行。如果正确,那么在查询行数之前,我将如何强制它“布置”文本?所有这些都需要在绘画事件之前发生。
list = QtGui.QListWidget()
text = QtGui.QTextEdit()
text.setHtml("Some html stuff in here that spans multiple lines")
fm = QtGui.QFontMetricsF(text.font())
height = text.document().lineCount() * fm.lineSpacing()
text.setFixedHeight(height + 10)
item = QtGui.QListWidgetItem()
item.setSizeHint(text.size())
list.addItem(item)
我不知道您到底想要什么,但是我想尝试一下。临近您想要的内容吗?
from PyQt4 import QtGui, QtCore
import sys
class CustomListView(QtGui.QListView):
def __init__(self, parent=None):
super(CustomListView, self).__init__(parent=None)
pass
class ListItem(object):
def __init__(self, html = "Some html stuff in here that spans multiple lines"*100):
self.html = html
class CustomListModel(QtCore.QAbstractListModel):
def __init__(self, parent=None):
super(CustomListModel, self).__init__(parent=None)
self.items = [ListItem()]
def rowCount(self, index=QtCore.QModelIndex()):
return len(self.items)
def columnCount(self, index= QtCore.QModelIndex()):
return 1
def data(self, index = QtCore.QModelIndex(), role=QtCore.Qt.ItemDataRole.DisplayRole):
row = index.row()
if role == QtCore.Qt.ItemDataRole.DisplayRole:
return self.items[row]
def setData(self, index, value, role=QtCore.Qt.EditRole):
if role == QtCore.Qt.EditRole:
row = index.row()
item = self.items[row]
item.html = value
return True
def flags(self, index):
return QtCore.Qt.ItemFlag.ItemIsEditable|QtCore.Qt.ItemFlag.ItemIsEnabled|QtCore.Qt.ItemFlag.ItemIsSelectable
class StyledItemDelegate(QtGui.QStyledItemDelegate):
def __init__(self, parent=None):
super(StyledItemDelegate, self).__init__(parent=None)
self.doc = QtGui.QTextDocument(self)
limitSize = QtCore.QSizeF(797, 1123)
self.doc.setPageSize(limitSize)
def paint(self, painter, option, index):
painter.save()
pen = painter.pen()
pen.setWidth(5)
pen.setStyle(QtCore.Qt.PenStyle.SolidLine)
painter.setPen(pen)
brush = painter.brush()
brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
brush.setColor(QtCore.Qt.blue)
painter.setBrush(brush)
data = index.data(QtCore.Qt.ItemDataRole.DisplayRole)
self.doc.setHtml(data.html)
option = QtGui.QStyleOptionViewItemV4(option)
style = QtGui.QApplication.style() if option.widget is None \
else option.widget.style()
textRect = style.subElementRect(QtGui.QStyle.SE_ItemViewItemText, option, None)
ctx = QtGui.QAbstractTextDocumentLayout.PaintContext()
ctx.clip = textRect
self.doc.drawContents(painter, ctx.clip)
painter.restore()
def sizeHint(self, option, index):
data = index.data(QtCore.Qt.ItemDataRole.DisplayRole)
self.doc.setHtml(data.html)
size = self.doc.size().toSize()
return size
def createEditor(self, parent, option, index):
data = index.data(QtCore.Qt.DisplayRole)
parent = QtGui.QTextEdit(parent)
parent.setFixedSize(self.sizeHint(option, index))
parent.setHtml(data.html)
return parent
def setEditorData(self, editor, index):
data = index.data(QtCore.Qt.DisplayRole)
editor.setHtml(data.html)
def setModelData(self, editor, model, index):
html = editor.toHtml()
model.setData(index, html)
def main():
if QtGui.QApplication.instance() is None:
app = QtGui.QApplication([])
else:
app = QtGui.QApplication.instance()
list = CustomListView()
model = CustomListModel()
list.setModel(model)
delegate = StyledItemDelegate()
list.setItemDelegate(delegate)
list.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()