获取空行的格式
Getting formatting of empty lines
我对 QTextBlock::iterator
的工作原理有点困惑:
文档在普通文本上显示了如何使用它的清晰示例:
QTextBlock::iterator it;
for (it = currentBlock.begin(); !(it.atEnd()); ++it) {
QTextFragment currentFragment = it.fragment();
if (currentFragment.isValid())
processFragment(currentFragment);
}
我在空文本行上遇到问题。在这些方面,
it = currentBlock.begin();
if(it.atEnd())
// returns true !
我仍然需要能够读取格式(字符和块)
我应该检查最后的块吗?除了新行之外,还有其他方法可以测试块吗?
我目前的解决方案:同时检查最后一个迭代器,与 "for" 循环分开,并测试它是否是文档中的最后一个块(如果我尝试获取最后一个块的片段在文档中,程序崩溃了)。
看来我在违背文档...我应该如何获取空行的格式?
编辑:
我的旧解决方案:
QTextBlock currentBlock = document()->findBlock(selStart);
QTextBlock lastBlock = document()->lastBlock();
while (currentBlock.isValid())
{
QTextBlock::iterator it = currentBlock.begin();
if(currentBlock != lastBlock && it.atEnd())
{
QTextFragment currentFragment = it.fragment();
if (currentFragment.isValid())
{
QTextCharFormat f = currentFragment.charFormat();
// do something
}
}
else
{
for (; !(it.atEnd()); ++it)
{
QTextFragment currentFragment = it.fragment();
if (currentFragment.isValid())
{
// do stuff
QTextCharFormat f = currentFragment.charFormat();
// do stuff
}
}
}
}
基于 Tarod 回答的新解决方案消除了一项测试(但似乎行为不太一致)
QTextBlock currentBlock = document()->findBlock(selStart);
QTextBlock lastBlock = document()->lastBlock();
while (currentBlock.isValid())
{
QTextBlock::iterator it = currentBlock.begin();
if(currentBlock != lastBlock && it.atEnd())
{
QTextCharFormat f = currentBlock.charFormat();
// do something
}
else
{
for (; !(it.atEnd()); ++it)
{
QTextFragment currentFragment = it.fragment();
if (currentFragment.isValid())
{
// do stuff
QTextCharFormat f = currentFragment.charFormat();
// do stuff
}
}
}
}
我仍然需要检查最后一个块并避免在空块时使用它,有时它会崩溃。
我认为问题在于您只是遍历 QTextBlock
并阅读其文本片段的内容。在这种情况下,对于一个空 QTextBlock
,如您所证明的,currentBlock.begin() == it.atEnd()
因为 QTextBlock
没有任何文本片段。
您应该遍历所有文档文本块,获取所需信息,如果需要,遍历每个文本块以阅读文本片段的序列。
在下面的示例中,#3 块是一个空行 (\n\n
)。尽管由于 QTextBlockFormat
和 QTextCharFormat
.
我们仍然有关于此文本块的信息,但您不会看到行 qDebug() << "I am a QTextBlock with text!"
打印出来
main.cpp
#include <QApplication>
#include "graphicstextitem_3.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
GraphicsTextItem_3 g3;
g3.show();
return a.exec();
}
graphicstextitem_3.h
#ifndef GRAPHICSTEXTITEM_3_H
#define GRAPHICSTEXTITEM_3_H
#include <QMainWindow>
class QGraphicsScene;
class QGraphicsView;
class QGraphicsTextItem;
class GraphicsTextItem_3 : public QMainWindow
{
Q_OBJECT
public:
explicit GraphicsTextItem_3(QMainWindow *parent = 0);
private:
QGraphicsScene *scene;
QGraphicsView *view;
QGraphicsTextItem *item;
signals:
public slots:
};
#endif // GRAPHICSTEXTITEM_3_H
graphicstextitem_3.cpp
#include "graphicstextitem_3.h"
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsTextItem>
#include <QTextCursor>
#include <QTextDocument>
#include <QTextBlock>
#include <QDebug>
GraphicsTextItem_3::GraphicsTextItem_3(QMainWindow *parent) : QMainWindow(parent)
{
scene = new QGraphicsScene(this);
view = new QGraphicsView(scene);
item = new QGraphicsTextItem("Block 0\n Block 1\n Block 2\n\n Block 4");
item->setTextInteractionFlags(Qt::TextEditorInteraction);
QFont f = item->font();
f.setPointSize(30);
item->setFont(f);
QTextDocument* doc = item->document();
for (QTextBlock it = doc->begin(); it != doc->end(); it = it.next())
{
QTextBlockFormat block_format = it.blockFormat();
QTextCharFormat char_format = it.charFormat();
qDebug() << "*** Block number: " << it.blockNumber()
<< " with text: " << it.text();
qDebug() << "* Block format info: "
<< " leftMargin: " << block_format.leftMargin()
<< " rightMargin: " << block_format.rightMargin()
<< " topMargin: " << block_format.topMargin()
<< " bottomMargin: " << block_format.bottomMargin()
<< " lineHeight: " << block_format.lineHeight();
qDebug() << "* Char format info: "
<< " pointSize: " << char_format.font().pointSize()
<< " fontFamily: " << char_format.font().family();
QTextBlock::iterator tb_it = it.begin();
if (tb_it.atEnd())
{
qDebug() << "it.begin() == tb_it.atEnd()";
/* The application crashes if we get the fragment */
// tb_it.fragment();
}
for (tb_it = it.begin(); !(tb_it.atEnd()); ++tb_it) {
QTextFragment currentFragment = tb_it.fragment();
if (currentFragment.isValid())
{
qDebug() << "I am a QTextBlock with text!"
<< " Out of here empty QTextBlock!"
<< " You - shall not - pass!";
}
}
}
scene->addItem(item);
view->setFixedSize(640, 480);
this->setCentralWidget(view);
}
这是伪代码(对我有用)。简而言之,当方法 atEnd()
returns TRUE
,然后你追加一个新的 line
.
QTextEdit * pwTextEdit = whatever your source;
QTextDocument * poDocument = pwTextEdit->document();
QTextBlock oTextBlock = poDocument->begin();
while (oTextBlock.isValid())
{
QTextBlock::iterator oTextBlockIterator(oTextBlock.begin());
while (TRUE)
{
if (oTextBlockIterator.atEnd())
{
// Append your '\n' here
break;
}
QTextFragment oTextFragment = oTextBlockIterator.fragment();
QString sText = oTextFragment.text();
// Process the text from sText
oTextBlockIterator++;
}
oTextBlock = oTextBlock.next();
}
我对 QTextBlock::iterator
的工作原理有点困惑:
文档在普通文本上显示了如何使用它的清晰示例:
QTextBlock::iterator it;
for (it = currentBlock.begin(); !(it.atEnd()); ++it) {
QTextFragment currentFragment = it.fragment();
if (currentFragment.isValid())
processFragment(currentFragment);
}
我在空文本行上遇到问题。在这些方面,
it = currentBlock.begin();
if(it.atEnd())
// returns true !
我仍然需要能够读取格式(字符和块)
我应该检查最后的块吗?除了新行之外,还有其他方法可以测试块吗?
我目前的解决方案:同时检查最后一个迭代器,与 "for" 循环分开,并测试它是否是文档中的最后一个块(如果我尝试获取最后一个块的片段在文档中,程序崩溃了)。
看来我在违背文档...我应该如何获取空行的格式?
编辑:
我的旧解决方案:
QTextBlock currentBlock = document()->findBlock(selStart);
QTextBlock lastBlock = document()->lastBlock();
while (currentBlock.isValid())
{
QTextBlock::iterator it = currentBlock.begin();
if(currentBlock != lastBlock && it.atEnd())
{
QTextFragment currentFragment = it.fragment();
if (currentFragment.isValid())
{
QTextCharFormat f = currentFragment.charFormat();
// do something
}
}
else
{
for (; !(it.atEnd()); ++it)
{
QTextFragment currentFragment = it.fragment();
if (currentFragment.isValid())
{
// do stuff
QTextCharFormat f = currentFragment.charFormat();
// do stuff
}
}
}
}
基于 Tarod 回答的新解决方案消除了一项测试(但似乎行为不太一致)
QTextBlock currentBlock = document()->findBlock(selStart);
QTextBlock lastBlock = document()->lastBlock();
while (currentBlock.isValid())
{
QTextBlock::iterator it = currentBlock.begin();
if(currentBlock != lastBlock && it.atEnd())
{
QTextCharFormat f = currentBlock.charFormat();
// do something
}
else
{
for (; !(it.atEnd()); ++it)
{
QTextFragment currentFragment = it.fragment();
if (currentFragment.isValid())
{
// do stuff
QTextCharFormat f = currentFragment.charFormat();
// do stuff
}
}
}
}
我仍然需要检查最后一个块并避免在空块时使用它,有时它会崩溃。
我认为问题在于您只是遍历 QTextBlock
并阅读其文本片段的内容。在这种情况下,对于一个空 QTextBlock
,如您所证明的,currentBlock.begin() == it.atEnd()
因为 QTextBlock
没有任何文本片段。
您应该遍历所有文档文本块,获取所需信息,如果需要,遍历每个文本块以阅读文本片段的序列。
在下面的示例中,#3 块是一个空行 (\n\n
)。尽管由于 QTextBlockFormat
和 QTextCharFormat
.
qDebug() << "I am a QTextBlock with text!"
打印出来
main.cpp
#include <QApplication>
#include "graphicstextitem_3.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
GraphicsTextItem_3 g3;
g3.show();
return a.exec();
}
graphicstextitem_3.h
#ifndef GRAPHICSTEXTITEM_3_H
#define GRAPHICSTEXTITEM_3_H
#include <QMainWindow>
class QGraphicsScene;
class QGraphicsView;
class QGraphicsTextItem;
class GraphicsTextItem_3 : public QMainWindow
{
Q_OBJECT
public:
explicit GraphicsTextItem_3(QMainWindow *parent = 0);
private:
QGraphicsScene *scene;
QGraphicsView *view;
QGraphicsTextItem *item;
signals:
public slots:
};
#endif // GRAPHICSTEXTITEM_3_H
graphicstextitem_3.cpp
#include "graphicstextitem_3.h"
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsTextItem>
#include <QTextCursor>
#include <QTextDocument>
#include <QTextBlock>
#include <QDebug>
GraphicsTextItem_3::GraphicsTextItem_3(QMainWindow *parent) : QMainWindow(parent)
{
scene = new QGraphicsScene(this);
view = new QGraphicsView(scene);
item = new QGraphicsTextItem("Block 0\n Block 1\n Block 2\n\n Block 4");
item->setTextInteractionFlags(Qt::TextEditorInteraction);
QFont f = item->font();
f.setPointSize(30);
item->setFont(f);
QTextDocument* doc = item->document();
for (QTextBlock it = doc->begin(); it != doc->end(); it = it.next())
{
QTextBlockFormat block_format = it.blockFormat();
QTextCharFormat char_format = it.charFormat();
qDebug() << "*** Block number: " << it.blockNumber()
<< " with text: " << it.text();
qDebug() << "* Block format info: "
<< " leftMargin: " << block_format.leftMargin()
<< " rightMargin: " << block_format.rightMargin()
<< " topMargin: " << block_format.topMargin()
<< " bottomMargin: " << block_format.bottomMargin()
<< " lineHeight: " << block_format.lineHeight();
qDebug() << "* Char format info: "
<< " pointSize: " << char_format.font().pointSize()
<< " fontFamily: " << char_format.font().family();
QTextBlock::iterator tb_it = it.begin();
if (tb_it.atEnd())
{
qDebug() << "it.begin() == tb_it.atEnd()";
/* The application crashes if we get the fragment */
// tb_it.fragment();
}
for (tb_it = it.begin(); !(tb_it.atEnd()); ++tb_it) {
QTextFragment currentFragment = tb_it.fragment();
if (currentFragment.isValid())
{
qDebug() << "I am a QTextBlock with text!"
<< " Out of here empty QTextBlock!"
<< " You - shall not - pass!";
}
}
}
scene->addItem(item);
view->setFixedSize(640, 480);
this->setCentralWidget(view);
}
这是伪代码(对我有用)。简而言之,当方法 atEnd()
returns TRUE
,然后你追加一个新的 line
.
QTextEdit * pwTextEdit = whatever your source;
QTextDocument * poDocument = pwTextEdit->document();
QTextBlock oTextBlock = poDocument->begin();
while (oTextBlock.isValid())
{
QTextBlock::iterator oTextBlockIterator(oTextBlock.begin());
while (TRUE)
{
if (oTextBlockIterator.atEnd())
{
// Append your '\n' here
break;
}
QTextFragment oTextFragment = oTextBlockIterator.fragment();
QString sText = oTextFragment.text();
// Process the text from sText
oTextBlockIterator++;
}
oTextBlock = oTextBlock.next();
}