我正在使用Qt的QSyntaxHighlighter在QML TextEdit中为某些类似于C的语法着色
除多行注释外,所有内容都很好。
我正以这种方式检测它们:
void highlightBlock(QString const& text) override {
bool inMultilineComment = previousBlockState() == STATES::COMMENT;
bool inSingleLineComment = false;
int previousIndex = 0;
QRegularExpression expr("(\\/\\*|\\*\\/|\\/\\/|\n)"); // will match either /**, /**, // or \n
QRegularExpressionMatchIterator it = expr.globalMatch(text);
while(it.hasNext()) {
QRegularExpressionMatch match = it.next();
const QString captured = match.captured(1);
if(captured == "/*" && !inSingleLineComment) {
inMultilineComment = true;
previousIndex = match.capturedStart(1);
}
if(captured == "*/" && inMultilineComment) {
inMultilineComment = false;
setFormat(previousIndex, match.capturedEnd(1) - previousIndex, _commentFormat);
}
if(captured == "//" && !inMultilineComment) {
inSingleLineComment = true;
}
if(captured == "\n" && inSingleLineComment) {
inSingleLineComment = false;
}
}
if(inMultilineComment) {
setFormat(previousIndex, text.size() - previousIndex, _commentFormat);
setCurrentBlockState(STATES::COMMENT);
}
else {
setCurrentBlockState(STATES::NONE);
}
}
它起作用,直到我接受已经着色的多行注释,并且一开始就删除了/*
。仅对包含/*
的块进行处理并重新上色,而对随后的块不进行处理并重新上色,这意味着它们在没有出现时会继续显示注释。
是否有一种简单的方法告诉QSyntaxHighlighter重新处理以下块以防止出现这种错误的颜色?
答案 0 :(得分:0)
我最近遇到了同样的问题,并发现Qt实际上应该为您处理此问题,前提是您正确设置了blockState。
如果您查看Qt5源代码中的QSyntaxHighlighterPrivate :: reformatBlocks的源代码,则会看到
while (block.isValid() && (block.position() < endPosition || forceHighlightOfNextBlock)) {
const int stateBeforeHighlight = block.userState();
reformatBlock(block);
forceHighlightOfNextBlock = (block.userState() != stateBeforeHighlight);
block = block.next();
}
从https://code.woboq.org/qt5/qtbase/src/gui/text/qsyntaxhighlighter.cpp.html#165撤回
该代码(由您的荧光笔打开的QTextDocument中的contentsChange信号触发)将从刚刚修改的块开始遍历每个块(行)。假设块的状态基于刚刚发生的类型更改而改变,它将继续处理以下块。这意味着您需要正确设置每一行的userState,而Qt应该处理其余的内容。
给出示例
/*
* This is a comment
*
* That I made
*/
您希望从以下条件开始:每行都设置了STATES::COMMENT
,但最后一行应设置为STATES::NONE
。完成删除初始/*
之类的操作后,您需要确保将阻止状态重置为STATES::NONE
。这将触发Qt重新运行下一个块,这也将需要更改其状态,等等。
在我的(python)代码中,我最终使用了打印语句和实际调试的组合来跟踪状态更改的传播,并找出错误地更新了哪些地方并打破了更新链。您的代码从表面上看是正确的,尽管我没有尝试编译并运行它,但是我怀疑在某些情况下会触发某些情况,即在编辑后状态无法正确更新。