1、概述
QUndoCommand
和 QUndoStack
是 Qt 框架中用于实现撤销/重做(undo/redo)功能的两个核心类。QUndoCommand
是表示单个可撤销操作的基类,而 QUndoStack
则负责管理这些命令的堆栈,提供撤销和重做操作的接口。
-
QUndoCommand:这是一个抽象基类,用于封装一个可以执行和撤销的操作。每个命令对象都必须实现
redo()
和undo()
方法,分别用于执行和撤销该命令。此外,命令还可以选择性地实现mergeWith()
方法,以便在可能的情况下将连续的操作合并为一个命令。 -
QUndoStack:这个类管理着一系列
QUndoCommand
对象,这些对象以堆栈的形式存储。QUndoStack
提供了push()
方法来添加新命令,undo()
和redo()
方法来分别撤销和重做命令。此外,它还提供了查询当前是否可以撤销或重做操作的接口,以及监听堆栈状态变化的信号。
2、重要方法
QUndoCommand:
redo()
:执行命令。undo()
:撤销命令。mergeWith(const QUndoCommand *other)
:尝试将当前命令与另一个命令合并。id()
:返回命令的唯一标识符(通常用于调试)。setText(const QString &text)
和text()
:设置和获取命令的描述文本。
QUndoStack:
push(QUndoCommand *command)
:将命令推送到堆栈上。undo()
:撤销堆栈顶部的命令。redo()
:重做最近撤销的命令。clear()
:清空堆栈。canUndo()
和canRedo()
:查询当前是否可以撤销或重做操作。undoText()
和redoText()
:获取当前可以撤销或重做的命令的描述文本。command(int index)
:获取堆栈中指定索引的命令。count()
:获取堆栈中命令的数量。
3、重要信号
QUndoStack 发出以下信号来通知堆栈状态的变化:
cleanChanged(bool clean)
:当堆栈变为干净(即没有可撤销的操作)或不干净时发出。canUndoChanged(bool canUndo)
:当可以撤销的操作数量发生变化时发出。canRedoChanged(bool canRedo)
:当可以重做的操作数量发生变化时发出。undoTextChanged(const QString &undoText)
:当可以撤销的操作的描述文本发生变化时发出。redoTextChanged(const QString &redoText)
:当可以重做的操作的描述文本发生变化时发出。
#include <QUndoCommand>
#include <QString>
#include <QDebug>
class TextEditCommand : public QUndoCommand
{
public:
TextEditCommand(const QString &oldText, const QString &newText, QString &textBuffer, int id = -1)
: m_oldText(oldText), m_newText(newText), m_textBuffer(textBuffer)
{
setText("Edit Text");
}
// 撤销操作
void undo() override
{
m_textBuffer = m_oldText;
qDebug() << "Undo: " << m_textBuffer;
}
// 重做操作
void redo() override
{
m_textBuffer = m_newText;
qDebug() << "Redo: " << m_textBuffer;
}
private:
QString m_oldText;
QString m_newText;
QString &m_textBuffer; // 引用要修改的文本
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString textBuffer = "Hello, world!";
// 创建一个撤销栈
QUndoStack undoStack;
// 执行第一次编辑操作
TextEditCommand *command1 = new TextEditCommand("Hello, world!", "Hello, Qt!", textBuffer);
undoStack.push(command1);
// 执行第二次编辑操作
TextEditCommand *command2 = new TextEditCommand("Hello, Qt!", "Hello, QUndo!", textBuffer);
undoStack.push(command2);
// 查看当前文本
qDebug() << "Current Text: " << textBuffer;
// 执行撤销操作
undoStack.undo();
// 查看撤销后的文本
qDebug() << "After Undo: " << textBuffer;
// 执行重做操作
undoStack.redo();
// 查看重做后的文本
qDebug() << "After Redo: " << textBuffer;
return a.exec();
}
觉得有帮助的话,打赏一下呗。。