无法在 TextEdit 上突出显示

Unable to get highlighting working on TextEdit

TL;DR: TextEdit 仅在我单击时绘制突出显示的文本。没有任何帮助

我有一个 ListView 和一个带有字符串属性的 QAbstractListModel 模型。 这些字符串属性正在接受拼写检查,QSyntaxHighlighter 用于显示拼写错误。我在 TextEditComponent.onCompleted 中创建 QSyntaxHighlighter 后代。我仔细检查了 highlighting get's executed with correct spell errors and setFormat() of Highlighter is executed with correct positions.问题是它仅在我单击 TextEdit 本身时才将文本绘制为红色(无效)。

TextEdit 生活在 Flickable(跟踪光标)和 Flickable 生活在 Rectangle(有漂亮的背景和边框)。绑定到某些信号并调用 TextEdit 的 update() 没有帮助。

拼写检查完成后,我发出创建 SyntaxHighlighter 的 rehighlight() 信号。

Rectangle {
  id: descriptionRect
  height: 30
  border.width: descriptionTextInput.activeFocus ? 1 : 0
  clip: true

  Flickable {
      id: descriptionFlick
      contentWidth: descriptionTextInput.paintedWidth
      contentHeight: descriptionTextInput.paintedHeight
      anchors.fill: parent
      interactive: false
      flickableDirection: Flickable.HorizontalFlick
      height: 30
      clip: true
      focus: false

      function ensureVisible(r) {
          if (contentX >= r.x)
              contentX = r.x;
          else if (contentX+width <= r.x+r.width)
              contentX = r.x+r.width-width;
      }

      TextEdit {
          id: descriptionTextInput
          width: descriptionFlick.width
          height: descriptionFlick.height
          text: description
          onTextChanged: model.editdescription = text

          Component.onCompleted: {
              globalModel.initDescriptionHighlighting(index, descriptionTextInput.textDocument)
          }

          onCursorRectangleChanged: descriptionFlick.ensureVisible(cursorRectangle)
         }
     }
 }

这是一个小项目示例,演示了在您单击文本之前它是如何工作的https://bitbucket.org/ribtoks/qt-highlighting-issue

有什么解决办法吗?

问题可能是由 QTBUG-44765 引起的,已在 Qt 5.5 中修复。

鉴于该错误的级别较低,我认为实际上无法解决它。

您可以通过在完成语法突出显示后向 TextEdit 附加一个空字符串来解决这个问题

TextEdit {
    id: captionTextEdit
    width: wrapperFlick.width
    height: wrapperFlick.height
    text: display
    readOnly: true

    Component.onCompleted: {
        itemsModel.initHighlighter(index, captionTextEdit.textDocument)
    }

    Connections {
        target: itemsModel
        onUpdateTextEdit: {
            console.log("Update element at index: " + indexToUpdate)

            if (indexToUpdate == index)
            {
                console.log("Update me!")
                captionTextEdit.append("")
            }
        }
    }

    onCursorRectangleChanged: wrapperFlick.ensureVisible(cursorRectangle)
}

其中 updateTextEdit(indexToUpdate) 是您的 itemsModel 必须发出的新信号。

itemsmodel.h

signals:
    void updateTextEdit(int indexToUpdate);

itemsmodel.cpp

void ItemsModel::initHighlighter(int index, QQuickTextDocument *document) {
    // Signal mapper could be avoided if lamda slot are available (Qt5 and C++11)
    QSignalMapper* signalMapper = new QSignalMapper(this);

    if (0 <= index && index < m_ItemsList.length()) {
        SingleItem *item = m_ItemsList.at(index);
        SpellCheckHighlighter *highlighter = new SpellCheckHighlighter(document->textDocument(), item);
        QObject::connect(item, SIGNAL(spellCheckResultsReady()),
                         highlighter, SLOT(rehighlight()));

        // TODO: Don't connect this slot for Qt 5.5+ to avoid performance overhead
        QObject::connect(item, SIGNAL(spellCheckResultsReady()),
                         signalMapper, SLOT(map()));
        signalMapper->setMapping(item, index);
    }

    connect(signalMapper, SIGNAL(mapped(int)),
            this, SIGNAL(updateTextEdit(int)));
}

此处提供完整代码:https://bitbucket.org/swarta/rehighlighdemo/branch/workaround#diff

刚刚在 5.11.2 上遇到这个问题并找到了以下修复程序,它允许更新单个块而无需 highlight/deselect 整个文本区域

rehighlightBlock(newBlock);
Q_EMIT document()->documentLayout()->updateBlock(newBlock);