我正在尝试使用
QTextLayout
逐条渲染线条。我尝试将 wrapMode
设置为 QTextOption::ManualWrap
并为每一行调用 QTextLine::setNumColumns
,但整个文本显示在一行中。
我还尝试将
wrapMode
设置为 QTextOption::WrapAnywhere
,这次文本被分成行,但空行(仅由 \n
组成的行)不可见。
我尝试链接
Qt4
和Qt5
,但没有结果。
我做错了什么?
您可以使用
QTextLine::setNumColumns()
来指定当前行适合的字符数,直到它中断。如果您知道文本行的长度,则可以在您想要的位置准确地断开每行。换行符似乎被 QTextLayout
忽略。
QTextOption opt;
opt.setWrapMode(QTextOption::WrapAnywhere);
QStringList text;
text.append("First line");
text.append("Another line");
layout.setText(text.join(""));
layout.beginLayout();
qreal h = 0;
for(const auto& line : text)
{
QTextLine l = layout.createLine();
if(!l.isValid()
break;
l.setNumColumns(line.length());
l.setPosition(QPointF(0, h);
h += l.height();
}
layout.endLayout();
其中
layout
是 QTextLayout
,您可以将其定义为小部件类或其他类中的成员。但请注意(至少在 Qt 4.8.x 中)如果您使用选项卡,这可能无法按预期工作。我尝试创建一个具有右侧和左侧制表位的布局(可以通过 QTextOption
和 QTextOption::Tab
配置),但我不知道如何让它正确设置换行符。计算以像素为单位的线宽也不容易,因为 QFontMetrics::size()
不支持除左对齐以外的制表位。
QTextLine
作者:QTextLayout.createLine();
QTextLayout
可以绘制一个QTextBlock
,ENTER字符或键是创建新的QTextBlock。因此,您必须为每个块绘制布局。
QTextBlock 不包含
"\n"
字符,因为该字符将文本拆分为新的 QTextBlock
我使用这个例子:
class KonuIcerik : public QGraphicsTextItem
{
public:
QRectF boundingRect() const
{
return QRectF( 0 , 0 , this->LineWidth , this->height );
}
int height;
int LineWidth;
int LineCountMod;
int CallNumber;
QString metin;
QFont font;
QTextEdit* textEdit;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
int y = 0 ;
CallNumber = 0;
int PageNumber = 1;
for( int i = 0 ; i < textEdit->document()->blockCount() ; i++ ){
QTextBlock block = textEdit->document()->findBlockByNumber(i);
QTextLayout layout(block);
layout.setFont(font);
layout.beginLayout();
while( true ){
QTextLine line = layout.createLine();
if( !line.isValid() ){
break;
}else{
if( CallNumber > 37 && (CallNumber-37) % LineCountMod == 0 ){
y += 300;
PageNumber++;
}
CallNumber++;
if( CallNumber == 37 ){
y += 300;
PageNumber++;
}
line.setLineWidth( LineWidth );
line.setPosition( QPointF( 0 , y ) );
y += line.height();
}
}
this->height = y;
layout.endLayout();
layout.draw(painter,QPointF(0,0));
}
}
void UPdate(){
update(-50,-50 , LineWidth+50 , height+50);
}
};
您参考该课程,如果“ ”包含。 我希望这有帮助。
我通过手动检查
QTextLine
中的换行符解决了这个问题
bool ElidedLabelPrivate::doTextLayout(QTextLayout &text_layout, int width,
int height) const {
/// if height <= 0 - no height limit
int line_spacing = QFontMetrics(text_layout.font()).lineSpacing();
qreal height_used = 0;
qreal width_used = 0;
const QString &text = text_layout.text();
while (true) {
QTextLine line = text_layout.createLine();
if (!line.isValid()) {
return true; // text fits available size
}
line.setLineWidth(width);
// check for line breaks
const QStringRef line_text =
text.midRef(line.textStart(), line.textLength());
if (line_text.contains('\n')) {
line.setNumColumns(line_text.indexOf('\n') + 1);
}
line.setPosition(QPointF(0, height_used));
height_used += line_spacing;
width_used = std::max(width_used, line.naturalTextWidth());
int current_pos = line.textStart() + line.textLength();
bool need_next_line = current_pos < text_layout.text().length();
bool can_insert_line =
(height <= 0) || (height_used + line_spacing <= height);
if (need_next_line && !can_insert_line) {
return false;
}
}
}