首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何访问QTextDocument的QUndoStack?

如何访问QTextDocument的QUndoStack?
EN

Stack Overflow用户
提问于 2010-06-08 05:28:43
回答 3查看 983关注 0票数 6

如何访问QTextDocumentQUndoStack

(例如,我希望能够将自定义QUndoCommand对象添加到文档的撤消堆栈中)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-06-11 00:46:02

我一直在阅读文档,这似乎不是一种直接为小部件获取QUndoStack的方法。

可能唯一的方法是创建您自己的QUndoStack对象,手动添加更改,然后重新实现redo() / undo()插槽。我会看一下源代码,您可能可以从中获得在QTextDocument中存储更改所需的大部分代码。

票数 4
EN

Stack Overflow用户

发布于 2010-07-18 21:25:20

没有办法:(

我使用的方法是根据需要修改QTextDocument类,然后重新编译Gui模块。

为此,静态链接是一个很好的选择。

票数 2
EN

Stack Overflow用户

发布于 2021-05-04 23:58:57

PySide2解决方案:无需重新实现!

背景和说明(代码和说明请跳到下面):

正如其他人所说,实际上,到2020年5月为止,似乎没有办法直接访问撤消堆栈。例如,Qt论坛上用户mrjj的This 2017 answer说堆栈存在于qtextdocument_p.cpp中,而没有办法通过接口访问它。

相反,每个人都建议实现您自己的undo-able命令,这是小菜一碟,但我没有找到这样有意义的实现。此外,内置功能在QTextDocument docs中有很好的文档记录,至少对我来说,重新实现它看起来不是太简单:

可以使用setUndoRedoEnabled()函数控制对文档执行的

撤消/重做操作。撤销/重做系统可以由编辑器小部件通过undo()和redo()插槽控制;文档还提供contentsChanged()、undoAvailable()和redoAvailable()信号,通知连接的编辑器小部件有关撤消/重做系统的状态。以下是QTextDocument的撤消/重做操作:

  • 插入或删除字符。同一文本块内的一系列插入或删除被视为单个撤消/重做operation.
  • Insertion或文本块删除。在单个操作中插入或删除的序列(例如,通过选择然后删除文本)被视为单个撤消/重做operation.
  • Text字符格式changes.
  • Text块格式changes.
  • Text块组格式更改。

正如我们所看到的,它集成了许多不同类型的复杂事件,最重要的是它具有命令压缩功能。我个人非常不喜欢重新实现它的想法。

理想情况下,我们将通过API访问堆栈,这样就完成了!希望这在某种程度上得到了支持(如果是这样的话,请在评论中告诉我)。在这个答案中,我展示了一种方法,可以用最少的努力集成内置的QTextDocument撤消堆栈,并保留其所有功能。我尝试了许多不同的方法,我最喜欢这一种。希望这能有所帮助!

代码和说明

这段代码举例说明了QPlainTextEdit的用法,但您也可以用其他小部件重现它。有关说明,请参阅文档字符串:

代码语言:javascript
复制
from PySide2 import QtWidgets, QtGui, QtCore


class TextDocumentUndoWrapperCommand(QtWidgets.QUndoCommand):
    """
    This command is a wrapper that simply uses the text document stack, but
    allows to register the action on a different stack for integration.
    """

    def __init__(self, txt_editor, parent=None):
        super().__init__("Text Document Action", parent)
        self.txt_editor = txt_editor

    def undo(self):
        self.txt_editor.document().undo()

    def redo(self):
        self.txt_editor.document().redo()


class TextEditor(QtWidgets.QPlainTextEdit):
"""
QTextDocument document has a really nice built-in undo stack, but
unfortunately it cannot be accessed or integrated with other undo stacks.
This class exemplifies such integration, as follows:

1. Important: we do NOT disable undo/redo functionality. We keep it on!
2. Every time that QTextDocument adds a Command to its own stack, we add
   a wrapper command to our own main stack
3. Every time the user sends an undo/redo event, we intercept it and send
   it through our wrapper command. This way we have effectively integrated
   the built-in undo stack into our own main stack.
"""

def __init__(self, parent=None, undo_stack=None):
    """
    """
    super().__init__(parent)
    self.setLineWrapMode(self.WidgetWidth)  # matter of taste
    if undo_stack is not None:
        # if we provide a stack, integrate internal stack with it
        self.installEventFilter(self)
        self.undo_stack = undo_stack
        self.document().undoCommandAdded.connect(self.handle_undo_added)

def handle_undo_added(self, *args, **kwargs):
    """
    The key information is WHEN to create an undo command. Luckily,
    the QTextDocument provides us that information. That way, we can keep
    both undo stacks in perfect sync.
    """
    cmd = TextDocumentUndoWrapperCommand(self)
    self.undo_stack.push(cmd)

def eventFilter(self, obj, evt):
    """
    We didn't deactivate the undo functionality. We simply want to
    re-route it through our stack, which is synched with the built-in
    one.
    """
    if evt.type() == QtCore.QEvent.KeyPress:
        if evt.matches(QtGui.QKeySequence.Undo):
            self.undo_stack.undo()
            return True
        if evt.matches(QtGui.QKeySequence.Redo):
            self.undo_stack.redo()
            return True
    return super().eventFilter(obj, evt)

然后,可以简单地将TextEditor用作常规小部件。如果我们不向构造函数提供堆栈,将使用默认的内置隐藏堆栈。如果我们提供了一个,包装器机制会将隐藏的堆栈集成到提供的堆栈中。

注意:我没有为“只是QTextDocument”提供解决方案,因为我不能让eventFilter为它工作(我很高兴听到其他人的努力)。在任何情况下,QTextDocument总是在任何类型的父小部件/窗口中,然后这个逻辑应该同样适用。有很多论坛要求这个功能,我认为这是最好的地方来发布这个答案(让我知道否则)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2993304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档