I have a TextItem
inheriting QGraphicsTextItem
. I made it so that on double-click I can edit the text, and when clicking out, the text is no longer editable.
void TextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * event)
{
setTextInteractionFlags(Qt::TextEditorInteraction);
setFocus();
int p = document()->documentLayout()->hitTest(event->pos(), Qt::FuzzyHit);
QTextCursor _cursor = textCursor();
_cursor.setPosition(p);
setTextCursor(_cursor);
}
void TextItem::focusOutEvent(QFocusEvent *event)
{
Q_UNUSED(event);
setTextInteractionFlags(Qt::NoTextInteraction);
}
When clicking out, the text is no longer editable - but the caret is still visible.
Adding setCursor(Qt::OpenHandCursor);
in the focusOutEvent
(and possibly trying to remember which cursor shape to set... I don't know how yet) fixes this - makes the caret disappear - but I don't think it is the right fix.
Yet I cannot find any method in QTextCursor
to hide the caret when no longer in edit mode - and it seems that setting NoTextInteraction
should have done that...
What is the best way to hide the caret when not in edit mode ?
You are talking of the caret - the on-screen indication of the text editing position. What you describe looks like a Qt bug.
The setCursor
call modifies the mouse pointer, not the caret. It has a side effect that forces the item to synchronize the caret state with the interaction flags. The absence of such synchronization is the bug you experience.
The QTextCursor
class doesn't represent the caret, but a position in the text document. It's a fancy iterator, completely decoupled from any visible representation of it.
The QGraphicsTextItem
happens to maintain a caret that represents the position of its textCursor
property. You can have other QTextCursor
instances operating on the same document, and they won't have a visible caret associated with them - they are just iterators.
You know one workaround for the bug - via setCursor
, but try the ones below, too:
An update()
of the item after the interaction has been disabled.
Setting the textCursor
to a null cursor, perhaps in combination with an update()
.
setTextCursor(QTextCursor());
Added a clear selection on lost focus, since it seems that not only the caret is left but any selected text is also left selected - and it is not the behavior I wanted.
void TextItem::focusOutEvent(QFocusEvent *event)
{
Q_UNUSED(event);
setTextInteractionFlags(Qt::NoTextInteraction);
QTextCursor _cursor = textCursor();
_cursor.clearSelection();
setTextCursor(_cursor);
}
The above clears the caret, as well as any selected text fragment.
(If anybody reading this question is looking to save selection on text fragments, but not display the caret, the option I mentioned in my question - by setting the QCursor
- may be the best option)