QTextLayout手动换行
QTextLayout manual line breaking
我试图使用QTextLayout
逐个渲染行。我尝试将wrapMode
设置为QTextOption::ManualWrap
,并为每行调用QTextLine::setNumColumns
,但整个文本出现在一行中。
我也尝试将wrapMode
设置为QTextOption::WrapAnywhere
,这次文本被分成几行,但空行(仅由n
组成的行)不可见。
我试着链接Qt4
和Qt5
,没有结果。
我做错了什么?
QTextLine用于单行文本。如果你想要多行,那么使用QTextEdit
事实证明,Qt
通过为每一行创建一个新的QTextLayout
来实现这一点。详细信息请参见QPlainTextEdit::paintEvent(QPaintEvent *)
源代码
您可以使用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
by 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);
}
};
引用这个类,如果"n"包含,就会看到新行。我希望这对你有帮助。
我通过手动检查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;
}
}
}
- 使用一个考虑到std::map中键值的滚动或换行的键
- 如何防止clang格式在流运算符调用之间添加换行符<<
- C/C++ - 查询平台相关的换行符(用于内存映射文件)
- 在 Stream C++ 文本之前有一个额外的换行符
- 流:CSV 文件中的换行符
- 将缓冲区复制到剪贴板 [换行错误]
- 如何在三元条件运算符中添加换行符和连接? :在 C++ 中
- Clang-格式:在多行语句之后的换行符上打开大括号
- 如何正确转发/换行static_cast?
- 在输出流中插入换行符
- 防止控制台在通道字符(在 c++ 中)中输入空格(即空格、制表符和换行符)
- QProcess::readAllStandardOutput() 和换行符
- 如果有换行符,clang 格式不会附加大括号
- 创建一个简单的前向迭代器,该迭代器在循环缓冲区的"end"处自动换行
- C++在标点符号后将字符串换行
- 提取后返回换行符的C++istream.get()
- 如何在出现换行符之前将多个整数作为输入?
- 正则表达式 获取两个换行符之间的文本
- 包含换行符分隔的单词的文件和C++中这些单词的字符串向量的大小是否相同?
- QTextLayout手动换行