Making changes to a QTextEdit without adding an undo command to the undo stack

2.7k views Asked by At

I'm looking for a way to change the QTextCharFormat of a QTextEdit's QTextBlock without triggering the addition of an undo command. Let me explain:

The QTextCharFormat of a QTextBlock can be easily changed by using the QTextCursor::setBlockCharFormat() method. Assuming we have a QTextEdit called myTextEdit whose visible cursor is within the text block we want to change, we can change the textblock's QTextCharFormat like so:

text_cursor = myTextEdit.textCursor()
text_cursor.setBlockCharFormat(someNewCharFormat)

The above code works fine, but it will also add an undo command to the myTextEdit undo stack. For my own purposes, I would like to be able to change the QTextCharFormat of a QTextBlock without adding an undo command to the QTextEdit's undo stack.

I considered temporarily disabling the undo/redo system with the QTextDocument::setUndoRedoEnabled() method, but that method also clears the undo stack, which I don't want to do. I've also looked for other ways to change how the undo/redo system behaves, but I haven't found a way to get it to temporarily ignore changes. I simply want to make a change to a QTextEdit without the undo/redo system registering the change at all.

Any tips or suggestions are appreciated. Thanks!

3

There are 3 answers

3
Marek R On

You have to group this with previous modification. It is simple you have to surround code which does this modification with: beginEditBlock and endEditBlock. See documentation.

text_cursor = myTextEdit.textCursor()
text_cursor.beginEditBlock()
text_cursor.setCharFormat(someOtherCharFormat) # some previous modification
text_cursor.setBlockCharFormat(someNewCharFormat)
text_cursor.endEditBlock()

this way you will make a single commit for undo stack for any complex modification.

0
jochen On

joinPreviousBlock() should do the trick:

cursor = self.textCursor()
cursor.joinPreviousEditBlock()
cursor.setPosition(start, QTextCursor.MoveAnchor)
cursor.setPosition(end, QTextCursor.KeepAnchor)
cursor.setCharFormat(fmt)
cursor.endEditBlock()
0
safu9 On

You should use QSyntaxHighlighter. Extends it and implement highlightBlock func, and call setFormat in it to change format without making undo/redo stack. See documentation for more detail.

If you feel QSyntaxHighlighter is not what you want, you can use QTextLayout. It is low level api and its setAdditionalFormats func doesn't make any undo stack.

range1 = QTextLayout.FormatRange()
range1.start = 0
range1.length = 10
range1.format = QTextCharFormat()
# additional ranges here...
textBlock.layout().setAdditionalFormats([range1, ...])

This is also used in the inside of QSyntaxHighlighter.