一、描述
1、QUndoStack类是QUndoCommand对象的堆栈。
2、QUndoStack跟踪当前命令。 这是下一次对redo()的调用将执行的命令。该命令的索引由index()返回。
1.1、撤销和回撤动作
QUndoStack提供了方便的撤消和回撤QAction对象,可以将其插入菜单或工具栏。撤消或回撤命令时,QUndoStack将更新这些操作的文本属性以反映它们将触发的更改。当没有命令可用于撤消或重做时,这些操作也将被禁用。这些动作由createUndoAction()和createRedoAction()返回。
1.2、命令压缩和宏
1、几个命令可以压缩为一个命令,并且可以在一个操作中撤消和回撤。
2、命令宏是一系列命令,所有这些命令都可以一次性撤消并回撤。通过为命令提供子命令列表来创建命令宏。撤消或回撤父命令将导致子命令被撤消或回撤。可以通过在QUndoCommand构造函数中指定一个父级或使用便利函数beginMacro()和endMacro()显式创建命令宏。
3、尽管命令压缩和宏对用户似乎具有相同的效果,但它们在应用程序中的用法常常不同。
- 如果用户只关注较大的更改,则将几个进行了小更改的命令进行压缩会更好。
- 对于比较关注详细更改的情况或无法压缩的命令,使用宏在维护每个命令的记录更好。
1.3、清洁状态
QUndoStack支持清洁状态的概念。如将文档保存到磁盘后,可以使用setClean()将堆栈标记为清洁。每当堆栈通过撤消和回撤命令返回到此状态时,它都会发出信号cleanChanged()。 当堆栈离开清洁状态时,也会发出此信号。 该信号通常用于启用和禁用应用程序中的保存操作。
1.4、过时的命令
如果不再需要命令,则QUndoStack可以从堆栈中删除命令。
二、属性成员
1、active : bool
此属性保存此堆栈的活动状态。
一个应用程序通常具有多个撤消堆栈,每个打开的文档一个。 活动堆栈是与当前活动文档关联的堆栈。如果堆栈属于QUndoGroup,则当它处于活动状态时,对QUndoGroup::undo()或QUndoGroup::redo()的调用将转发到该堆栈。 如果QUndoView监视了QUndoGroup,则该视图在活动时将显示该堆栈的内容。 如果堆栈不属于QUndoGroup,则使其处于活动状态不起作用。通常,当关联的文档窗口获得焦点时,程序员需要通过调用setActive()来指定哪个堆栈处于活动状态。
2、canRedo : bool
此属性指示是否存在可以重做的命令。
3、canUndo : bool
此属性指示是否存在可以撤消的命令。
4、clean : bool
此属性保存此堆栈的清洁状态。
5、redoText : QString
此属性保存下一个回撤的命令的回撤文本。
6、undoLimit : int
此属性保存此堆栈上的最大命令数。
当堆栈上的命令数量超过堆栈的undoLimit时,将从堆栈底部删除命令。 宏命令(带有子命令的命令)被视为一个命令。默认值为0,表示没有限制。仅当撤消堆栈为空时才可以设置此属性,因为在非空堆栈上进行设置可能会删除当前索引处的命令。在非空堆栈上调用setUndoLimit()会显示警告,但不执行任何操作。
7、undoText : QString
此属性保存下一个撤消的命令的撤消文本。
三、成员函数
1、QUndoStack(QObject *parent = nullptr)
构造一个空的撤消堆栈。堆栈最初将处于清洁状态。 如果parent是QUndoGroup对象,则堆栈会自动添加到组中。
2、[signal] void indexChanged(int idx)
撤消或回撤命令时都会发出此信号。 撤消或回撤宏命令或调用setIndex()时,此信号仅发出一次。idx指定当前命令的索引,即。该命令将在下次调用redo()时执行。
3、void redo()
通过调用QUndoCommand::redo()回撤当前命令。递增当前命令索引。如果堆栈为空,或者已经回撤了堆栈上的top命令,则此功能不执行任何操作。如果QUndoCommand::isObsolete()对于当前命令返回true,则将从堆栈中删除该命令。
4、void setIndex(int idx)
重复调用undo()或redo(),直到当前命令索引达到idx。此功能可用于使状态向前或向后滚动。 indexChanged()仅发出一次。
5、void undo()
通过调用QUndoCommand::undo()撤销当前命令下方的命令。 减少当前命令索引。如果堆栈为空,或者堆栈上的底部命令已被撤销,则此功能不执行任何操作。撤消命令后,如果QUndoCommand::isObsolete()返回true,则将从堆栈中删除该命令。
6、void beginMacro(const QString &text)
从给定的文本描述开始组成宏命令。由指定文本描述的空命令被压入堆栈。压入堆栈的所有后续命令都将附加到空命令的子级中,直到调用endMacro()为止。可以嵌套对beginMacro()和endMacro()的调用,但是对beginMacro()的每次调用都必须具有对endMacro()的匹配调用。
stack.beginMacro("插入红色文本");
stack.push(new InsertText(document, idx, text));
stack.push(new SetColor(document, idx, text.length(), Qt::red));
stack.endMacro();
以上代码等同于:
QUndoCommand *insertRed = new QUndoCommand(); //空命令
insertRed->setText("插入红色文本");
new InsertText(document, idx, text, insertRed); //成为空命令的子命令
new SetColor(document, idx, text.length(), Qt::red, insertRed);
stack.push(insertRed);
7、void clear()
情况堆栈中的命令。
8、const QUndoCommand *command(int index)
通过索引获取命令。
9、int count()
返回堆栈上的命令数。 宏命令被视为一个命令。
10、QAction *createRedoAction(QObject *parent, const QString &prefix = QString())
使用给定的父级创建一个重做QAction对象。触发此操作将导致对redo()的调用。 此操作的文本是命令的文本,该命令的文本将在下一次对redo()的调用中重做,并以指定的前缀为前缀。 如果没有可用于重做的命令,此操作将被禁用。
如果前缀为空,则使用默认模板“"Redo %1”代替前缀。
11、QAction *createUndoAction(QObject *parent, const QString &prefix = QString())
与上面类似。
12、void endMacro()
结束宏命令的合成。如果这是一组嵌套宏中最外面的宏,则此函数对整个宏命令发出一次indexChanged()。
13、int index()
返回当前命令的索引。 这是将在下次调用redo()时执行的命令。 由于许多命令可能已被撤消,因此它并不总是堆栈上最顶层的命令。
14、bool isClean()
是否是清洁状态。
15、void push(QUndoCommand *cmd)
将cmd推入堆栈或将其与最近执行的命令合并。如果cmd的ID不为-1,并且该ID与最近执行的命令的ID相同,则QUndoStack将通过对最近执行的命令调用QUndoCommand::mergeWith()来尝试合并两个命令。(将命令push入堆栈之后会删除堆栈中已撤销的命令。命令入堆栈后会执行一次redo())
16、QString text(int idx)
返回索引为idx的命令的文本。