在不向撤消堆栈添加撤消命令的情况下更改 QTextEdit
Posted
技术标签:
【中文标题】在不向撤消堆栈添加撤消命令的情况下更改 QTextEdit【英文标题】:Making changes to a QTextEdit without adding an undo command to the undo stack 【发布时间】:2014-11-24 20:07:58 【问题描述】:我正在寻找一种方法来更改QTextEdit
的QTextCharFormat
的QTextBlock
而不触发添加撤消命令。让我解释一下:
QTextBlock
的QTextCharFormat
可以使用QTextCursor::setBlockCharFormat()
方法轻松更改。假设我们有一个名为myTextEdit
的QTextEdit
,其可见光标在我们要更改的文本块内,我们可以像这样更改文本块的QTextCharFormat
:
text_cursor = myTextEdit.textCursor()
text_cursor.setBlockCharFormat(someNewCharFormat)
上面的代码可以正常工作,但它也会在myTextEdit
undo 堆栈中添加一个撤消命令。出于我自己的目的,我希望能够更改 QTextBlock
的 QTextCharFormat
而不向 QTextEdit
的撤消堆栈添加撤消命令。
我考虑使用QTextDocument::setUndoRedoEnabled()
方法暂时禁用撤消/重做系统,但该方法也会清除撤消堆栈,我不想这样做。我还寻找其他方法来更改撤消/重做系统的行为方式,但我还没有找到一种方法让它暂时忽略更改。我只是想对QTextEdit
进行更改,而无需撤消/重做系统注册更改。
感谢任何提示或建议。谢谢!
【问题讨论】:
我认为你可能不走运,请参阅this qt-interest thread(有点旧,但它很好地总结了问题)。 【参考方案1】:您必须将此与之前的修改分组。很简单,你必须用beginEditBlock
和endEditBlock
包围进行此修改的代码。见documentation。
text_cursor = myTextEdit.textCursor()
text_cursor.beginEditBlock()
text_cursor.setCharFormat(someOtherCharFormat) # some previous modification
text_cursor.setBlockCharFormat(someNewCharFormat)
text_cursor.endEditBlock()
这样,您将针对任何复杂的修改为撤消堆栈进行一次提交。
【讨论】:
嗨马雷克。感谢您的建议!不幸的是,这个解决方案不能满足我的需要。我真的需要根本没有添加撤消命令。我需要这个的原因是我正在尝试扩展撤消/重做系统以跟踪和更改默认情况下不跟踪的整个程序的属性。这意味着,当撤消操作时,我正在执行可以被视为撤消操作一部分的附加代码。在我的例子中,setBlockCharFormat() 方法将作为撤消的一部分运行,因此不应将撤消命令添加到堆栈中。 所以尝试undo
然后在编辑块redo
中进行更改。
beginEditBlock() 正是将许多操作折叠成一个撤消/重做步骤的原因。这很难找到。谢谢!我们正要重构 QTextDocument 以使用 QUndoStack。这为我们节省了 1 周的工作时间。 ?【参考方案2】:
joinPreviousBlock() 应该可以解决问题:
cursor = self.textCursor()
cursor.joinPreviousEditBlock()
cursor.setPosition(start, QTextCursor.MoveAnchor)
cursor.setPosition(end, QTextCursor.KeepAnchor)
cursor.setCharFormat(fmt)
cursor.endEditBlock()
【讨论】:
【参考方案3】:您应该使用QSyntaxHighlighter。对其进行扩展并实现highlightBlock
func,并在其中调用setFormat
以更改格式而不进行撤消/重做堆栈。详情请参阅documentation。
如果你觉得 QSyntaxHighlighter 不是你想要的,你可以使用QTextLayout。它是低级 api,它的setAdditionalFormats
func 不会做任何撤消堆栈。
range1 = QTextLayout.FormatRange()
range1.start = 0
range1.length = 10
range1.format = QTextCharFormat()
# additional ranges here...
textBlock.layout().setAdditionalFormats([range1, ...])
这也用在QSyntaxHighlighter内部。
【讨论】:
以上是关于在不向撤消堆栈添加撤消命令的情况下更改 QTextEdit的主要内容,如果未能解决你的问题,请参考以下文章
使用 QUndoCommand 的子级/父级推送多个命令以一次撤消堆栈