QTextLayout 手动换行
QTextLayout manual line breaking
我正在尝试使用 QTextLayout
一条一条地渲染线条。我尝试将 wrapMode
设置为 QTextOption::ManualWrap
并为每一行调用 QTextLine::setNumColumns
但整个文本显示在一行中。
我还尝试将 wrapMode
设置为 QTextOption::WrapAnywhere
,这次文本被分成几行,但空行(仅由 \n
组成的行)是不可见。
我已经尝试 link 对抗 Qt4
和 Qt5
但没有结果。
我做错了什么?
QTextLine is used for single line text. If you want multiple lines then use QTextEdit.
事实证明,Qt
通过为每一行创建一个新的 QTextLayout
来实现这一点。详情请见QPlainTextEdit::paintEvent(QPaintEvent *)
source.
您可以使用 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
,您可以将其定义为小部件 class 或其他任何内容中的成员。但请注意(至少在 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);
}
};
你参考这个 class 如果“\n”包含,你会看到新行。
希望对您有所帮助。
我正在尝试使用 QTextLayout
一条一条地渲染线条。我尝试将 wrapMode
设置为 QTextOption::ManualWrap
并为每一行调用 QTextLine::setNumColumns
但整个文本显示在一行中。
我还尝试将 wrapMode
设置为 QTextOption::WrapAnywhere
,这次文本被分成几行,但空行(仅由 \n
组成的行)是不可见。
我已经尝试 link 对抗 Qt4
和 Qt5
但没有结果。
我做错了什么?
QTextLine is used for single line text. If you want multiple lines then use QTextEdit.
事实证明,Qt
通过为每一行创建一个新的 QTextLayout
来实现这一点。详情请见QPlainTextEdit::paintEvent(QPaintEvent *)
source.
您可以使用 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
,您可以将其定义为小部件 class 或其他任何内容中的成员。但请注意(至少在 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);
}
};
你参考这个 class 如果“\n”包含,你会看到新行。 希望对您有所帮助。