Solved QSyntaxHighlighter does not create QTextFragments
-
Hi,
I'm working on a syntax highlighter with Qt and I wanted to add unit tests on it to check if formats are well applied.
But I don't manage to get the block divided by formats. I use QTextBlock and QTextFragment but it's not working while the doc of QTextFragment says :A text fragment describes a piece of text that is stored with a single character format.
Here is the code in a runnable main.cpp file :
#include <QApplication> #include <QTextEdit> #include <QSyntaxHighlighter> #include <QRegularExpression> #include <QDebug> class Highlighter : public QSyntaxHighlighter { public: Highlighter(QTextDocument *parent) : QSyntaxHighlighter(parent) {} protected: void highlightBlock(const QString& text) override { QTextCharFormat classFormat; classFormat.setFontWeight(QFont::Bold); QRegularExpression pattern { "\\bclass\\b" }; QRegularExpressionMatchIterator matchIterator = pattern.globalMatch(text); while (matchIterator.hasNext()) { QRegularExpressionMatch match = matchIterator.next(); setFormat(match.capturedStart(), match.capturedLength(), classFormat); } // ==== TESTS ==== // qDebug() << "--------------------------------"; QTextDocument *doc = document(); QTextBlock currentBlock = doc->firstBlock(); while (currentBlock.isValid()) { qDebug() << "BLOCK" << currentBlock.text(); QTextBlockFormat blockFormat = currentBlock.blockFormat(); QTextCharFormat charFormat = currentBlock.charFormat(); QFont font = charFormat.font(); // each QTextBlock holds multiple fragments of text, so iterate over it: QTextBlock::iterator it; for (it = currentBlock.begin(); !(it.atEnd()); ++it) { QTextFragment currentFragment = it.fragment(); if (currentFragment.isValid()) { // a text fragment also has a char format with font: QTextCharFormat fragmentCharFormat = currentFragment.charFormat(); QFont fragmentFont = fragmentCharFormat.font(); qDebug() << "FRAGMENT" << currentFragment.text(); } } currentBlock = currentBlock.next(); } } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); auto *textEdit = new QTextEdit; auto *highlighter = new Highlighter(textEdit->document()); Q_UNUSED(highlighter); textEdit->setText("a class for test"); textEdit->show(); return a.exec(); }
And it outputs only one block "a class for test" and one format "a class for test" while the class keyword is in bold.
Thanks for your help !
-
Ok I found this from the documentation of QSyntaxHighlighter::setFormat :
Note that the document itself remains unmodified by the format set through this function.
The formats applied by the syntax highlighter are not stored in QTextBlock::charFormat but in the additional formats :
QVector<QTextLayout::FormatRange> formats = textEdit->textCursor().block().layout()->formats();