qt重没有该接口,很郁闷,经过多方研究,甚至阅读qt源码,终于找到一种方法
从源码中抽出一个方法
void qt_format_text(const QFont &fnt, const QRectF &_r,
int tf, const QTextOption *option, const QString& str, QRectF *brect,
int tabstops, int *ta, int tabarraylen,
QPainter *painter)
{
Q_ASSERT( !((tf & ~Qt::TextDontPrint)!=0 && option!=0) ); // we either have an option or flags
if (option) {
tf |= option->alignment();
if (option->wrapMode() != QTextOption::NoWrap)
tf |= Qt::TextWordWrap;
if (option->flags() & QTextOption::IncludeTrailingSpaces)
tf |= Qt::TextIncludeTrailingSpaces;
if (option->tabStop() >= 0 || !option->tabArray().isEmpty())
tf |= Qt::TextExpandTabs;
}
// we need to copy r here to protect against the case (&r == brect).
QRectF r(_r);
bool dontclip = (tf & Qt::TextDontClip);
bool wordwrap = (tf & Qt::TextWordWrap) || (tf & Qt::TextWrapAnywhere);
bool singleline = (tf & Qt::TextSingleLine);
bool showmnemonic = (tf & Qt::TextShowMnemonic);
bool hidemnmemonic = (tf & Qt::TextHideMnemonic);
qDebug()<<"wordwrap is:"<<wordwrap;
Qt::LayoutDirection layout_direction;
if (tf & Qt::TextForceLeftToRight)
layout_direction = Qt::LeftToRight;
else if (tf & Qt::TextForceRightToLeft)
layout_direction = Qt::RightToLeft;
else if (option)
layout_direction = option->textDirection();
else if (painter)
layout_direction = painter->layoutDirection();
else
layout_direction = Qt::LeftToRight;
//tf = QGuiApplicationPrivate::visualAlignment(layout_direction, QFlag(tf));
bool isRightToLeft = layout_direction == Qt::RightToLeft;
bool expandtabs = ((tf & Qt::TextExpandTabs) &&
(((tf & Qt::AlignLeft) && !isRightToLeft) ||
((tf & Qt::AlignRight) && isRightToLeft)));
if (!painter)
tf |= Qt::TextDontPrint;
uint maxUnderlines = 0;
QFontMetricsF fm(fnt);
QString text = str;
int offset = 0;
start_lengthVariant:
bool hasMoreLengthVariants = false;
// compatible behaviour to the old implementation. Replace
// tabs by spaces
int old_offset = offset;
for (; offset < text.length(); offset++) {
QChar chr = text.at(offset);
if (chr == QLatin1Char('\r') || (singleline && chr == QLatin1Char('\n'))) {
text[offset] = QLatin1Char(' ');
} else if (chr == QLatin1Char('\n')) {
text[offset] = QChar::LineSeparator;
} else if (chr == QLatin1Char('&')) {
++maxUnderlines;
} else if (chr == QLatin1Char('\t')) {
if (!expandtabs) {
text[offset] = QLatin1Char(' ');
} else if (!tabarraylen && !tabstops) {
tabstops = qRound(fm.width(QLatin1Char('x'))*8);
}
} else if (chr == QChar(ushort(0x9c))) {
// string with multiple length variants
hasMoreLengthVariants = true;
break;
}
}
QVector<QTextLayout::FormatRange> underlineFormats;
int length = offset - old_offset;
if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) {
QChar *cout = text.data() + old_offset;
QChar *cout0 = cout;
QChar *cin = cout;
int l = length;
while (l) {
if (*cin == QLatin1Char('&')) {
++cin;
--length;
--l;
if (!l)
break;
if (*cin != QLatin1Char('&') && !hidemnmemonic && !(tf & Qt::TextDontPrint)) {
QTextLayout::FormatRange range;
range.start = cout - cout0;
range.length = 1;
range.format.setFontUnderline(true);
underlineFormats.append(range);
}
}
*cout = *cin;
++cout;
++cin;
--l;
}
}
qreal height = 0;
qreal width = 0;
QString finalText = text.mid(old_offset, length);
QTextLayout textLayout(finalText);
textLayout.setFont(fnt);
textLayout.setCacheEnabled(true);
textLayout.setFormats(underlineFormats);
if (finalText.isEmpty()) {
height = fm.height();
width = 0;
tf |= Qt::TextDontPrint;
} else {
qreal lineWidth = 0x01000000;
if (wordwrap || (tf & Qt::TextJustificationForced))
lineWidth = qMax<qreal>(0, r.width());
if(!wordwrap)
tf |= Qt::TextIncludeTrailingSpaces;
textLayout.beginLayout();
qreal leading = fm.leading();
leading=25;//此处控制行高,核心之处
height = -leading;
qDebug()<<QString("leading is:%1").arg(leading);
while (1) {
QTextLine l = textLayout.createLine();
if (!l.isValid())
break;
l.setLineWidth(lineWidth);
height += leading;
// Make sure lines are positioned on whole pixels
height = qCeil(height);
l.setPosition(QPointF(0., height));
width = qMax(width, l.naturalTextWidth());
if (!dontclip && !brect && height >= r.height())
break;
}
textLayout.endLayout();
}
qreal yoff = 0;
qreal xoff = 0;
if (tf & Qt::AlignBottom)
yoff = r.height() - height;
else if (tf & Qt::AlignVCenter)
yoff = (r.height() - height)/2;
if (tf & Qt::AlignRight)
xoff = r.width() - width;
else if (tf & Qt::AlignHCenter)
xoff = (r.width() - width)/2;
QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height);
if (hasMoreLengthVariants && !(tf & Qt::TextLongestVariant) && !r.contains(bounds)) {
offset++;
goto start_lengthVariant;
}
if (brect)
*brect = bounds;
if (!(tf & Qt::TextDontPrint)) {
bool restore = false;
if (!dontclip && !r.contains(bounds)) {
restore = true;
painter->save();
painter->setClipRect(r, Qt::IntersectClip);
}
for (int i = 0; i < textLayout.lineCount(); i++) {
qDebug()<<QString("at text line:%1").arg(i);
QTextLine line = textLayout.lineAt(i);
xoff = 0;
line.draw(painter, QPointF(r.x() + xoff, r.y() + yoff));
}
if (restore) {
painter->restore();
}
}
}
调用的时候把drawText替换成以下形式就可以了
//painter.drawText(QRect(leftSpace, totalHeight, viewRect.width()-2*leftSpace, textAreaHeight),Qt::TextWordWrap|Qt::AlignLeft, ui->imageViewText->toPlainText());
qt_format_text(font, QRect(leftSpace, totalHeight, viewRect.width()-2*leftSpace-40, textAreaHeight), Qt::TextWordWrap|Qt::AlignLeft, 0, ui->imageViewText->toPlainText(), 0, 0, 0, 0, &painter);