QUndoStack Class
QUndoStack 类是一个由QUndoCommand 对象组成的栈。更多内容...
| 头文件: | #include <QUndoStack> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Gui) target_link_libraries(mytarget PRIVATE Qt6::Gui) |
| qmake: | QT += gui |
| 继承自: | QObject |
属性
公共函数
| QUndoStack(QObject *parent = nullptr) | |
| virtual | ~QUndoStack() |
| void | beginMacro(const QString &text) |
| bool | canRedo() const |
| bool | canUndo() const |
| int | cleanIndex() const |
| void | clear() |
| const QUndoCommand * | command(int index) const |
| int | count() const |
| QAction * | createRedoAction(QObject *parent, const QString &prefix = QString()) const |
| QAction * | createUndoAction(QObject *parent, const QString &prefix = QString()) const |
| void | endMacro() |
| int | index() const |
| bool | isActive() const |
| bool | isClean() const |
| void | push(QUndoCommand *cmd) |
| QString | redoText() const |
| void | setUndoLimit(int limit) |
| QString | text(int idx) const |
| int | undoLimit() const |
| QString | undoText() const |
公共槽位
| void | redo() |
| void | resetClean() |
| void | setActive(bool active = true) |
| void | setClean() |
| void | setIndex(int idx) |
| void | undo() |
信号
| void | canRedoChanged(bool canRedo) |
| void | canUndoChanged(bool canUndo) |
| void | cleanChanged(bool clean) |
| void | indexChanged(int idx) |
| void | redoTextChanged(const QString &redoText) |
| void | undoTextChanged(const QString &undoText) |
详细说明
有关 Qt 撤销框架的概述,请参阅概述文档。
撤销堆栈用于维护已应用于文档的命令堆栈。
新命令使用push() 推入堆栈。可以使用undo() 和redo(),或者通过触发createUndoAction() 和createRedoAction() 返回的操作来撤销和重做命令。
QUndoStack 负责跟踪 `current ` 命令。该命令将在下次调用 `redo()` 时被执行。`index()` 会返回该命令的索引。 可通过setIndex()将编辑对象的状态向前或向后回滚。如果栈顶的命令已被重做,则index()等于count()。
QUndoStack 支持撤销和重做操作、命令压缩、命令宏,并支持“干净状态”的概念。
撤销和重做操作
QUndoStack 提供了便捷的撤销和重做QAction 对象,可将其插入菜单或工具栏中。当撤销或重做命令时,QUndoStack 会更新这些操作的文本属性,以反映它们将触发的更改。 当没有可撤销或重做的命令时,这些操作也会被禁用。QUndoStack::createUndoAction() 和QUndoStack::createRedoAction() 会返回这些操作。
命令压缩与宏
当多个命令可以压缩为单个命令,且该命令可通过单次操作进行撤销和重做时,命令压缩就非常有用。例如,当用户在文本编辑器中输入一个字符时,会创建一个新命令。该命令将该字符插入到文档的光标位置。 然而,对于用户而言,能够撤销或重做整个单词、句子或段落的输入会更加方便。命令压缩允许将这些单字符命令合并为一个命令,该命令可插入或删除文本片段。有关更多信息,请参阅QUndoCommand::mergeWith() 和push()。
命令宏是一系列命令,所有这些命令都会被一次性撤销或重做。通过为一个命令指定一组子命令来创建命令宏。 撤销或重做父命令将导致子命令被相应地撤销或重做。命令宏可以通过在QUndoCommand 构造函数中指定父命令来显式创建,也可以通过使用便捷函数beginMacro() 和endMacro() 来创建。
尽管对用户而言,命令压缩和宏似乎具有相同的效果,但在应用程序中它们的用途往往不同。对于那些对文档仅进行微小更改的命令,如果无需单独记录它们,且只有较大更改对用户才重要,则对其进行压缩会很有用。 然而,对于需要单独记录的命令,或者无法压缩的命令,使用宏既能提供更便捷的用户体验,又能保留每条命令的记录,因此非常有用。
干净状态
QUndoStack 支持“干净状态”的概念。当文档保存到磁盘时,可以使用 `setClean()` 将堆栈标记为干净状态。 每当堆栈通过撤销和重做命令返回此状态时,它会发出信号cleanChanged()。当堆栈离开“干净状态”时,也会发出此信号。该信号通常用于启用和禁用应用程序中的保存操作,并更新文档标题以反映其中包含未保存的更改。
已弃用的命令
如果某个命令不再需要,QUndoStack 能够将其从堆栈中删除。例如,当两个命令合并后,合并后的命令不再具有任何功能时,就可以删除该命令。这在移动命令中很常见:用户将鼠标移动到屏幕的某处,然后又将其移回原位。 合并后的命令会导致鼠标移动距离为 0。由于该命令毫无作用,因此可以将其删除。另一个例子是因连接问题而失败的网络命令。在这种情况下,应将该命令从堆栈中移除,因为由于存在连接问题,redo() 和undo() 函数已无实际作用。
可通过QUndoCommand::setObsolete() 函数将命令标记为过时。在调用QUndoCommand::undo()、QUndoCommand::redo() 和QUndoCommand:mergeWith()(如适用)之后,QUndoStack::push()、QUndoStack::undo()、QUndoStack::redo() 以及QUndoStack::setIndex() 会检查QUndoCommand::isObsolete() 标志。
如果某个命令被标记为已弃用,且清理索引大于或等于当前命令索引,则当该命令从堆栈中删除时,清理索引将被重置。
另请参阅 QUndoCommand 和QUndoView 。
属性文档
active : bool
该属性保存了此撤销堆栈的活动状态。
应用程序通常拥有多个撤销堆栈,每个已打开的文档对应一个。活动堆栈即与当前活动文档关联的那个。如果该堆栈属于QUndoGroup ,当其处于活动状态时,对QUndoGroup::undo()或QUndoGroup::redo()的调用将被转发至该堆栈。 如果QUndoGroup 被QUndoView 监视,则当该堆栈处于活动状态时,视图将显示其内容。如果堆栈不属于QUndoGroup ,则将其设为活动状态不会产生任何效果。
程序员有责任通过调用 setActive() 来指定哪个堆栈处于活动状态,通常是在关联的文档窗口获得焦点时进行。
访问函数:
| bool | isActive() const |
| void | setActive(bool active = true) |
另请参阅 QUndoGroup 。
[read-only] canRedo : bool
该属性表示此堆栈是否支持“重做”操作。
该属性指示是否存在可撤销的命令。
访问函数:
| bool | canRedo() const |
通知信号:
| void | canRedoChanged(bool canRedo) |
另请参阅 canRedo()、index() 和canUndo()。
[read-only] canUndo : bool
该属性表示此堆栈是否支持撤销操作。
该属性指示是否存在可撤销的命令。
访问函数:
| bool | canUndo() const |
通知信号:
| void | canUndoChanged(bool canUndo) |
另请参阅 canUndo()、index() 和canRedo()。
[read-only] clean : bool
该属性保存了此堆栈的“已清理”状态。
该属性指示栈是否处于“已清理”状态。例如,当文档已保存时,栈即处于“已清理”状态。
访问函数:
| bool | isClean() const |
通知信号:
| void | cleanChanged(bool clean) |
另请参阅 isClean()、setClean()、resetClean() 以及cleanIndex()。
[read-only] redoText : QString
该属性存储了下一个将被重做的命令的重做文本。
该属性存储将在下次调用redo()时被重做的命令的文本。
访问函数:
| QString | redoText() const |
通知信号:
| void | redoTextChanged(const QString &redoText) |
另请参阅 redoText()、QUndoCommand::actionText() 以及undoText()。
undoLimit : int
该属性用于指定此栈中命令的最大数量。
当栈中的命令数量超过该栈的 undoLimit 时,将从栈底删除命令。宏命令(包含子命令的命令)被视为一个命令。默认值为 0,这意味着没有限制。
该属性仅可在撤销栈为空时设置,因为在非空栈上设置该属性可能会删除当前索引处的命令。在非空栈上调用 setUndoLimit() 会输出警告信息,但不会执行任何操作。
访问函数:
| int | undoLimit() const |
| void | setUndoLimit(int limit) |
[read-only] undoText : QString
该属性存储了下一个将被撤销的命令的撤销文本。
该属性存储将在下次调用 `undo()` 时被撤销的命令的文本。
访问函数:
| QString | undoText() const |
通知信号:
| void | undoTextChanged(const QString &undoText) |
另请参阅 undoText()、QUndoCommand::actionText() 和redoText()。
成员函数文档
[explicit] QUndoStack::QUndoStack(QObject *parent = nullptr)
使用父对象parent 构建一个空的撤销堆栈。该堆栈初始状态为“干净”状态。如果parent 是一个QUndoGroup 对象,则该堆栈会自动添加到该组中。
另请参阅 push()。
[virtual noexcept] QUndoStack::~QUndoStack()
清除撤销堆栈,删除其中包含的所有命令。如果该堆栈位于QUndoGroup 中,则该堆栈会自动从该组中移除。
另请参阅 QUndoStack()。
void QUndoStack::beginMacro(const QString &text)
开始编写具有给定text 描述的宏命令。
将由指定的text 描述的空命令压入栈中。此后压入栈中的任何命令都将作为该空命令的子命令追加,直到调用endMacro()为止。
对 `beginMacro()` 和 `endMacro()` 的调用可以嵌套,但每次调用 `beginMacro()` 都必须有一个对应的 `endMacro()` 调用。
在宏组合过程中,栈功能会被禁用。这意味着:
- indexChanged() 和cleanChanged() 不会被生成,
- canUndo() 和canRedo() 返回 false,
- 调用 `undo()` 或 `redo()` 不会产生任何效果,
- 撤销/重做操作将被禁用。
当为最外层宏调用endMacro() 时,堆栈将启用,并发出相应的信号。
stack.beginMacro("insert red text");
stack.push(new InsertText(document, idx, text));
stack.push(new SetColor(document, idx, text.length(), Qt::red));
stack.endMacro(); // indexChanged() is emitted此代码等同于:
QUndoCommand *insertRed = new QUndoCommand(); // an empty command
insertRed->setText("insert red text");
new InsertText(document, idx, text, insertRed); // becomes child of insertRed
new SetColor(document, idx, text.length(), Qt::red, insertRed);
stack.push(insertRed);另请参阅 endMacro()。
bool QUndoStack::canRedo() const
如果存在可重做的命令,则返回true ;否则返回false 。
如果栈为空,或者栈顶命令已被重做,则此函数返回 `false `。
注意: 这是属性 canRedo 的获取 函数。
[signal] void QUndoStack::canRedoChanged(bool canRedo)
每当canRedo()的值发生变化时,都会触发此信号。它用于启用或禁用createRedoAction()返回的“重做”操作。canRedo 指定新值。
注意: 这是属性canRedo 的通知器 信号。
bool QUndoStack::canUndo() const
如果存在可撤销的命令,则返回true ;否则返回false 。
如果命令栈为空,或者栈底的命令已被撤销,则该函数返回 `false `。
等同于index() == 0。
注意: 这是 canUndo 属性的获取 函数。
[signal] void QUndoStack::canUndoChanged(bool canUndo)
每当canUndo()的值发生变化时,都会触发此信号。它用于启用或禁用createUndoAction()返回的撤销操作。canUndo 指定新值。
注意: 这是属性 `canUndo`的通知器 信号。
[signal] void QUndoStack::cleanChanged(bool clean)
每当栈进入或离开干净状态时,都会发出此信号。如果clean 为真,则栈处于干净状态;否则,该信号表示栈已离开干净状态。
注意: 这是属性clean 的通知器 信号。
int QUndoStack::cleanIndex() const
返回“干净索引”。这是调用setClean() 时的索引位置。
堆栈可能不具备“干净索引”。这种情况通常发生在文档被保存后,部分命令被撤销,随后又向堆栈中压入了一条新命令。由于push()会在压入新命令之前删除所有已撤销的命令,因此堆栈无法再次恢复到“干净”状态。 在此情况下,该函数返回 -1。在显式调用resetClean() 之后,也可能返回 -1。
void QUndoStack::clear()
通过删除命令堆栈中的所有命令来清空该堆栈,并将堆栈恢复为初始状态。
命令不会被撤销或重做;被编辑对象的状态保持不变。
当文档内容被放弃时,通常会使用此函数。
另请参阅 QUndoStack()。
const QUndoCommand *QUndoStack::command(int index) const
返回指向位于index 处的命令的常量指针。
该函数返回一个 const 指针,因为一旦命令被压入栈并执行,如果随后撤销或重做该命令,修改该命令几乎总是会导致文档状态损坏。
另请参阅 QUndoCommand::child()。
int QUndoStack::count() const
返回栈中命令的数量。宏命令计为一条命令。
另请参阅 index()、setIndex() 和command()。
QAction *QUndoStack::createRedoAction(QObject *parent, const QString &prefix = QString()) const
创建一个带有给定parent 的QAction 重做对象。
触发此操作将导致调用redo()。此操作的文本即为将在下次调用redo() 时被重做的命令文本,其前缀为指定的prefix 。如果没有可重做的命令,此操作将被禁用。
如果prefix 为空,则使用默认模板“Redo %1”代替前缀。在 Qt 4.8 之前,默认使用前缀“Redo”。
另请参阅 createUndoAction()、canRedo() 和QUndoCommand::text()。
QAction *QUndoStack::createUndoAction(QObject *parent, const QString &prefix = QString()) const
创建一个带有给定parent 的QAction 撤销对象。
触发此操作将导致调用undo()。此操作的文本即为下次调用undo() 时将被撤销的命令文本,其前缀为指定的prefix 。如果没有可撤销的命令,此操作将被禁用。
如果prefix 为空,则使用默认模板“Undo %1”代替前缀。在 Qt 4.8 之前,默认使用前缀“Undo”。
另请参阅 createRedoAction()、canUndo(),以及QUndoCommand::text()。
void QUndoStack::endMacro()
结束宏命令的编写。
如果这是一组嵌套宏中最外层的宏,则该函数会为整个宏命令调用一次indexChanged()。
另请参阅 beginMacro()。
int QUndoStack::index() const
返回当前命令的索引。这是下次调用 `redo()` 时将要执行的命令。它不一定是栈顶的命令,因为可能已有若干命令被撤销。
另请参阅 setIndex()、undo()、redo() 以及count()。
[signal] void QUndoStack::indexChanged(int idx)
每当某个命令修改文档的状态时,都会发出此信号。这通常发生在撤销或重做命令时。当撤销或重做宏命令,或者调用setIndex()时,此信号仅发出一次。
idx 指定当前命令的索引,即下次调用redo() 时将执行的命令。
bool QUndoStack::isClean() const
如果栈处于“clean”状态,则返回true ;否则返回false 。
注意: 这是属性clean 的获取器 函数。
另请参见 setClean() 和cleanIndex()。
void QUndoStack::push(QUndoCommand *cmd)
将cmd 压入栈中,或将其与最近执行的命令合并。无论哪种情况,都会通过调用其redo()函数来执行cmd 。
如果 `cmd` 的 id 不为 -1,且该 id 与最近执行的命令的 id 相同,则 `QUndoStack ` 将尝试通过在最近执行的命令上调用 `QUndoCommand::mergeWith()` 来合并这两个命令。如果 `QUndoCommand::mergeWith()` 返回 `true`,则 `cmd ` 将被删除。
在调用QUndoCommand::redo() 以及(如适用)QUndoCommand::mergeWith() 之后,将针对cmd 或合并后的命令调用QUndoCommand::isObsolete()。如果QUndoCommand::isObsolete() 返回true ,则cmd 或合并后的命令将从栈中删除。
在所有其他情况下,cmd 仅会被压入堆栈。
如果在将cmd 压入栈之前已撤销了某些命令,则当前命令及其上方的所有命令都会被删除。因此,cmd 最终总会成为栈顶。
一旦命令被压入栈中,栈便对其拥有所有权。没有用于返回该命令的获取器,因为在命令执行后对其进行修改几乎总是会导致文档状态的损坏。
另请参阅 QUndoCommand::id() 和QUndoCommand::mergeWith()。
[slot] void QUndoStack::redo()
通过调用 `QUndoCommand::redo()` 重新执行当前命令。将当前命令索引递增。
如果命令栈为空,或者栈顶的命令已被重做,则此函数不执行任何操作。
如果QUndoCommand::isObsolete() 对于当前命令返回 true,则该命令将从栈中删除。此外,如果清理索引大于或等于当前命令索引,则清理索引将被重置。
QString QUndoStack::redoText() const
返回将在下次调用 `redo()` 时被重做的命令文本。
注意: 这是属性 redoText 的获取 函数。
另请参阅 QUndoCommand::actionText() 和undoText()。
[signal] void QUndoStack::redoTextChanged(const QString &redoText)
每当redoText()的值发生变化时,都会触发此信号。它用于更新createRedoAction()返回的“重做”操作的text属性。redoText 指定新的文本内容。
注意: 这是属性redoText 的通知器 信号。
[slot] void QUndoStack::resetClean()
如果栈处于干净状态,则退出干净状态并调用cleanChanged()。此方法将干净索引重置为-1。
通常在以下情况下调用此方法,即当文档:
- 基于某个模板创建且尚未保存,因此该文档尚未关联文件名。
- 从备份文件中恢复。
- 在编辑器外部被修改,且用户未重新加载该文档。
另请参见 isClean()、setClean() 和cleanIndex()。
[slot] void QUndoStack::setClean()
将栈标记为“干净”,如果栈此前尚未处于“干净”状态,则调用cleanChanged()。
通常在保存文档时会调用此方法,例如。
每当栈通过撤销/重做命令返回此状态时,都会发出cleanChanged() 信号。当栈离开“干净”状态时,也会发出此信号。
另请参阅 isClean()、resetClean() 和cleanIndex()。
[slot] void QUndoStack::setIndex(int idx)
反复调用undo() 或redo(),直到当前命令索引达到idx 。该函数可用于将文档的状态向前或向后回滚。indexChanged() 仅触发一次。
另请参阅 index()、count()、undo() 和redo()。
QString QUndoStack::text(int idx) const
返回索引位置为idx 处的命令文本。
另请参阅 beginMacro()。
[slot] void QUndoStack::undo()
通过调用QUndoCommand::undo()来撤销当前命令下方的命令。将当前命令索引递减。
如果堆栈为空,或者堆栈底部的命令已被撤销,则此函数不执行任何操作。
撤销命令后,如果 `QUndoCommand::isObsolete()` 返回 `true`,则该命令将从堆栈中删除。此外,如果清理索引大于或等于当前命令索引,则清理索引将被重置。
QString QUndoStack::undoText() const
返回将在下次调用 `undo()` 时被撤销的命令的文本。
注意: 这是属性 undoText 的获取 函数。
另请参阅 QUndoCommand::actionText() 和redoText()。
[signal] void QUndoStack::undoTextChanged(const QString &undoText)
每当undoText()的值发生变化时,都会触发此信号。它用于更新createUndoAction()返回的撤销操作的text属性。undoText 指定新的文本内容。
注意: 这是属性undoText 的通知器 信号。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.