我有一个派生自QStyleOptionViewItem的自定义委托,它试图在paint方法中绘制多行(wordwrap)一长行文本。在做了一些搜索和Qt doc阅读之后,我看起来我需要使用QTextLayout来完成这样的任务,下面是我仍然将文本放在一行中的代码,任何有关如何围绕QStyleOptionViewItem长度包装线的提示传入?谢谢!
void Delegate::paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
painter->save();
painter->translate(option.rect.topLeft());
QString title = index.data(Qt::DisplayRole).toString();
QTextLayout * layout = new QTextLayout(title, QApplication::font());
layout->beginLayout();
QTextLine line = layout->createLine();
while (line.isValid()) {
line.setLineWidth(option.rect.width());
line = layout->createLine();
}
layout->endLayout();
layout->draw(painter, QPointF(0, 0));
painter->restore();
}
由于我无法自行回答,我将在此发表我的发现。 我发现我的代码有几个问题:
这是我在Ruby中的paint方法:
def paint painter, styleOptionViewItem, modelIndex
painter.save
painter.translate styleOptionViewItem.rect.top_left
marked_text = modelIndex.data(Qt::DisplayRole).value
font = Qt::Application::font()
text_layout = Qt::TextLayout.new marked_text
text_layout.setFont font
text_option = Qt::TextOption.new
text_option.setWrapMode(Qt::TextOption::WrapAtWordBoundaryOrAnywhere)
text_layout.setTextOption text_option
text_layout.beginLayout
fm = Qt::FontMetrics.new font
font_height = fm.height
i = 0
while i< LINE_LIMIT do
line = text_layout.createLine
break if (!line.isValid())
line.setLineWidth(styleOptionViewItem.rect.width)
line.setPosition(Qt::PointF.new(0, font_height * i))
i += 1
end
text_layout.endLayout
text_layout.draw painter, Qt::PointF.new(0, 0)
painter.restore
end
答案 0 :(得分:6)
我必须做一段时间同样的任务。
虽然我使用简单的QPainter::drwText
,但我遇到了这个问题。
要进行自动换行,您应该:
uniformRowHeight
视图属性。正确处理sizeHint
。默认情况下,此函数返回0
,您应该覆盖它以返回项目数据的Qt::SizeHint
角色。
但您还应为Qt::SizeHint
角色设置正确的值。您可以使用QFontMetrics::boundingRect
来计算sizeHint
,但在计算sizeHint
和绘制项目时,应确保使用相同的字体。在Windows 7
我遇到了问题,QStandardItem
的字体与QListView
的字体不一致。
请注意,每次请求时都从头开始计算sizeHint
是个坏主意,因为它的效果非常慢。