Qt撤销回/撤框架:QUndoCommand

Qt撤销回/撤框架:QUndoCommand

一、描述

1、QUndoCommand表示对文档的单个编辑操作。例如,在文本编辑器中插入或删除文本块。QUndoCommand可以使用redo()将更改应用于文档,并使用undo()撤消更改。这些功能的实现必须在派生类中提供。如:

2、QUndoCommand对象由它们被压入的堆栈所拥有。如果命令已被撤消并且推送了新命令,则QUndoStack会删除该命令。例如:

MyCommand *command1 = new MyCommand();

stack->push(command1);

MyCommand *command2 = new MyCommand();

stack->push(command2);

stack->undo();

MyCommand *command3 = new MyCommand();

stack->push(command3); // command2被删除

3、当一个命令被push时,它将成为堆栈中最上面的命令。

4、为了支持命令压缩,QUndoCommand有一个id()和虚拟函数mergeWith()。这些函数由QUndoStack::push()使用。

5、为了支持命令宏,一个QUndoCommand对象可以有任意数量的子命令。撤消或重做父命令将导致撤消或重做子命令。可以在构造函数中将命令显式分配给父级。在这种情况下,命令将由父级拥有。

6、父级很多时候是一个空命令,空命令在于它不提供自己的undo()和redo()实现。相反,它使用这些函数的基本实现,只需对其所有子函数调用undo()或redo()。但是,父级应该有一个有意义的text()。

二、成员函数

1、QUndoCommand(const QString &text, QUndoCommand *parent = nullptr)

构造一个QUndoCommand对象。如果parent不是nullptr,则此命令将附加到parent的子列表中。然后,父命令拥有此命令,并将在其析构函数中将其删除。

2、QString actionText()

返回一个简短的文本字符串,描述此命令的作用; 例如“插入文本”。

3、const QUndoCommand *child(int index)

获取子命令。

4、[virtual] int id()

返回此命令的ID。命令ID用于命令压缩。如果命令不支持压缩,则必须为-1。如果命令支持压缩,则必须在派生类中重写此功能以返回正确的ID。QUndoStack::push()将仅尝试合并两个具有相同ID且ID不为-1的命令。

5、bool isObsolete()

返回命令是否过时。

6、[virtual] bool mergeWith(const QUndoCommand *command)

尝试将此命令与command合并。成功返回true,否则返回false。如果此函数返回true,则调用此命令的redo()必须与回撤此命令和命令具有相同的效果。同样,调用此命令的undo()必须与撤消命令和此命令具有相同的效果。如果两个命令具有相同的ID,并且ID不为-1,则QUndoStack仅尝试合并两个命令。默认实现返回false。

7、[virtual] void redo()

回撤。此函数必须在派生类中实现。默认实现是在所有子命令上调用redo()。

8、void setObsolete(bool obsolete)

设置命令是否过时。

9、void setText(const QString &text) / QString QUndoCommand::text() const

设置描述此命令作用的文本。

10、[virtual] void undo()

撤销。此函数必须在派生类中实现。默认实现是以相反的顺序在所有子命令上调用undo()。

三、一个使用示例:使用撤销/回撤框架添加和撤销添加按钮的例子

#include

#include

class AddBtnCommand : public QUndoCommand

{

public:

AddBtnCommand(QWidget *doc, QUndoCommand *parent = 0);

void undo() Q_DECL_OVERRIDE;

void redo() Q_DECL_OVERRIDE;

private:

QWidget * doc;

class QPushButton * btn{nullptr};

};

AddBtnCommand::AddBtnCommand(QWidget *doc, QUndoCommand *parent):

QUndoCommand(parent),

doc(doc)

{

}

void AddBtnCommand::undo()

{

if(btn)

{

btn->deleteLater();

btn = nullptr;

}

}

void AddBtnCommand::redo()

{

if(!btn)

{

btn = new QPushButton("新建按钮",doc);

btn->move(20,20);

btn->show();

}

}

继承QUndoCommand实现添加按钮的命令,undo()中删除按钮,redo()中再次添加按钮。

使用命令:

Form::Form(QWidget *parent) :

QWidget(parent),

ui(new Ui::Form)

{

ui->setupUi(this);

undoStack = new QUndoStack(this);

}

//添加命令

void Form::on_pushButton_clicked()

{

undoStack->push(new AddBtnCommand(this));

}

//撤销操作

void Form::on_pushButton_2_clicked()

{

undoStack->undo();

}

//回撤操作

void Form::on_pushButton_3_clicked()

{

undoStack->redo();

}

把命令添加到QUndoStack中后会执行一次命令的redo()。

效果:

相关推荐

腾讯来电lightalk常见问题FAQ
注册送365

腾讯来电lightalk常见问题FAQ

📅 07-14 👁️ 6420
淞的解释
注册送365

淞的解释

📅 08-03 👁️ 9802