Reputation: 6922
TL;DR: TextEdit
paints highlighted text only when I click on it. Nothing helps
I have a ListView
with a QAbstractListModel
model with string properties.
Those string properties are being spellchecked and QSyntaxHighlighter
is used to show spell errors. I create QSyntaxHighlighter
descendant in Component.onCompleted
of TextEdit
. I double-checked highlighting get's executed with correct spell errors and setFormat()
of Highlighter is executed with correct positions. The problem is that it draws text in red (invalidates) only when I click on the TextEdit
itself.
TextEdit
lives in a Flickable
(to track cursor) and Flickable
lives in a Rectangle
(to have nice background and border). Binding to some signals and calling update() of TextEdit
does not help.
After spellcheck finishes, I emit rehighlight()
signal of created SyntaxHighlighter.
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)
}
}
}
Here is a small sample of project with demonstration of how it does not work until you click on a text https://bitbucket.org/ribtoks/qt-highlighting-issue
Any ideas how I can solve this?
Upvotes: 8
Views: 1168
Reputation: 446
Just encountered this issue on 5.11.2 and found the following fix which allows updating of individual blocks without having to highlight/deselect the whole text area
rehighlightBlock(newBlock);
Q_EMIT document()->documentLayout()->updateBlock(newBlock);
Upvotes: 1
Reputation: 11408
The issue was probably caused by QTBUG-44765, fixed in Qt 5.5.
Given the low level of the bug, I don't think it is practically to work around it.
You can work around that by appending an empty string to the TextEdit when you're done with the syntax highlighting
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)
}
where updateTextEdit(indexToUpdate)
is a new signal your itemsModel has to emit.
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)));
}
Full code is available here: https://bitbucket.org/swarta/rehighlighdemo/branch/workaround#diff
Upvotes: 1