【问题标题】:QSyntaxHighlighter and multiline commentsQSyntaxHighlighter 和多行注释
【发布时间】:2018-06-24 18:49:59
【问题描述】:

我正在使用 Qt 的 QSyntaxHighlighter 为 QML TextEdit 中的一些类似 C 的语法着色

除了多行 cmets,一切都很好。

我以这种方式检测它们:

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 重新处理以下块以防止此类错误着色?

【问题讨论】:

    标签: c++ qt syntax-highlighting


    【解决方案1】:

    我最近遇到了同样的问题,发现 Qt 实际上应该为你处理这个问题,假设你正确设置了你的 blockState。

    如果你查看 Qt5 源代码中 QSyntaxHighlighterPrivate::reformatBlocks 的 sourceCode,你会看到

    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) 代码中,我最终使用了打印语句和实际调试的组合来跟踪状态更改的传播,并找出它没有正确更新和中断更新链的地方。您的代码表面上看起来是正确的,虽然我没有尝试编译和运行它,但我怀疑在某些情况下触发了编辑后状态未正确更新的情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-04
      • 2014-01-15
      • 2010-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多