在未将撤销命令添加到撤销堆栈的情况下更改QTextEdit

7
我正在寻找一种方法来更改 QTextEditQTextBlockQTextCharFormat,而不触发撤销命令的添加。让我解释一下:
可以通过使用 QTextCursor::setBlockCharFormat() 方法轻松更改 QTextBlockQTextCharFormat。假设我们有一个名为 myTextEditQTextEdit,其可见光标位于我们想要更改的文本块中,我们可以这样更改文本块的 QTextCharFormat
text_cursor = myTextEdit.textCursor()
text_cursor.setBlockCharFormat(someNewCharFormat)

上面的代码可以正常工作,但它也会将撤销命令添加到myTextEdit的撤销堆栈中。为了满足自己的需求,我想能够更改QTextBlock的QTextCharFormat,而不向QTextEdit的撤销堆栈添加撤销命令。 我考虑使用QTextDocument::setUndoRedoEnabled()方法暂时禁用撤销/重做系统,但该方法还会清除撤销堆栈,这是我不想做的。我还寻找其他改变撤销/重做系统行为的方法,但我没有找到让它暂时忽略更改的方法。我只是想在不注册更改的情况下对QTextEdit进行更改。
感谢任何提示或建议。谢谢!

1
我认为你可能运气不佳,可以参考这个qt-interest线程(虽然有点旧,但总结了问题得很好)。 - ekhumoro
3个回答

8

您需要将此修改与先前的修改分组。很简单,您只需用以下代码包围执行此修改的代码:beginEditBlockendEditBlock。请参见文档

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

这样做可以为任何复杂的修改创建一个撤销堆栈,从而只需提交一次。

1
嗨Marek。感谢您的建议!不幸的是,这个解决方案并不能满足我的需求。我真的需要完全没有撤销命令。我需要这样做的原因是我正在尝试扩展撤销/重做系统以跟踪和更改整个程序的属性,而这些属性默认情况下是不被跟踪的。这意味着当一个操作被撤销时,我会执行额外的代码,这可以被视为撤销操作的一部分。在我的情况下,setBlockCharFormat()方法将作为撤销的一部分运行,因此不应该向堆栈中添加撤销命令。 - user3483225
尝试使用“撤销”命令,然后在编辑块中使用“重做”命令,最后进行您的更改。 - Marek R
beginEditBlock() 正是将多个操作合并为一个撤销/重做步骤的关键。这很难找到,谢谢!我们本来要重构 QTextDocument 以使用 QUndoStack,但这节省了我们一周的工作。 - Macke

4

使用joinPreviousBlock()函数即可解决问题:

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

3
你应该使用 QSyntaxHighlighter。继承它并实现 highlightBlock 函数,在其中调用 setFormat 函数以在不生成撤销/重做栈的情况下更改格式。有关详细信息,请参阅文档
如果你觉得 QSyntaxHighlighter 不符合要求,可以使用 QTextLayout。这是一个低级别的 API,并且它的 setAdditionalFormats 函数不会产生任何撤销栈。
range1 = QTextLayout.FormatRange()
range1.start = 0
range1.length = 10
range1.format = QTextCharFormat()
# additional ranges here...
textBlock.layout().setAdditionalFormats([range1, ...])

这也被用于QSyntaxHighlighter的内部。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接