【问题标题】:Getting formatting of empty lines获取空行的格式
【发布时间】:2015-12-29 19:13:23
【问题描述】:

我对@9​​87654321@ 的工作原理有点困惑:

文档在普通文本上显示了如何使用它的清晰示例:

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
            }
        }
    }
}

我仍然需要检查最后一个块,如果为空,请避免使用它,有时它会崩溃。

【问题讨论】:

    标签: qt formatting qgraphicsitem qgraphicstextitem


    【解决方案1】:

    我认为问题在于您只是在迭代 QTextBlock 并读取其文本片段的内容。在这种情况下,对于一个空的QTextBlock,正如您所证明的那样,currentBlock.begin() == it.atEnd() 因为QTextBlock 没有任何文本片段。

    您应该遍历所有文档文本块,获取所需信息,如果需要,遍历每个文本块以读取文本片段序列。

    在下面的例子中,#3 块是一个空行 (\n\n)。尽管感谢QTextBlockFormatQTextCharFormat,我们仍有关于此文本块的信息,但您不会看到打印的qDebug() << "I am a QTextBlock with text!" 行。

    ma​​in.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);
    }
    

    【讨论】:

    • 谢谢你的例子。你的方法 - 花了我一分钟时间看到 - 是相似的 - 你从 begin() 的所有块中提取信息 - 它处理空块以及其他非空块。它消除了单独测试 end 的需要。一个问题 - 我需要能够在选择而不是整个文档上执行此操作。如果块不是空的,但选择不是从块的开头开始,我总是从错误的片段中读取信息,这总是会导致错误的输出。
    • 我可能会坚持我的方法......事实上我的代码有效 - 我可以从一个空块中提取一个有效片段 - 当it.begin() == it.end() - 令人费解 - 但我可以提取一个来自空块的有效片段,并使用charFormat() 检查其格式,就像在正常循环中一样,即使使用blockCharFormat() 也不行。但是看看你的例子,我没有意识到在这种情况下我可以从it 本身提取格式并且不需要片段。
    • 你的代码很不错。使用我的代码,如果我们在空块中尝试提取片段并且iterator::atEnd() 为真,应用程序将崩溃。我已经更新了代码来说明这一点。如果您在空块中有文本(即possible!),则QTextFragment::isValid() 可能会有所不同。
    【解决方案2】:

    这是伪代码(对我有用)。简而言之,当atEnd() 方法返回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();
    }
    

    【讨论】:

      猜你喜欢
      • 2020-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-14
      • 2020-08-24
      • 2015-04-16
      • 1970-01-01
      • 2016-09-15
      相关资源
      最近更新 更多