Qt 的撤销回退事件
日期
作者
版本
12月16日
Mister H
V1.0
前言
在工作中有时候需要撤销和回退(重做)功能,而在网上的资料大多都相同且较复杂,研究了一段时间,终于看出了点门道出来,下面与大家分享一下。
一、QUndoCommand?
Qt 想要实现撤销回退功能,必须通过QUndoCommand去重写undo()(撤销)、redo()(回退)这两个虚函数去实现,下面是Qt 自带帮助文档介绍QUndoCommand。
QUndoCommand类是存储在QUndoStack上的所有命令的基类。
QUndoCommand表示文档上的单个编辑操作;例如,在文本编辑器中插入或删除文本块。QUndoCommand可以使用redo()对文档应用更改,并使用undo()撤销更改。这些函数的实现必须在派生类中提供。
二、重写QUndoCommand类
1.头文件
看到这里,相信大家对Qt 的QUndoCommand有了一个简单的了解,下面写了一个简单的例子,教大家如何重写QUndoCommand去实现的。
(示例 QTableWidget里面单元格撤销与回退)代码如下:
class AddCommand : public QUndoCommand
{
public:
AddCommand(QTableWidget *tableItem,int row, int column, QString content,QUndoCommand *parent = 0);
~AddCommand();
//撤销
void undo() override;
//回退
void redo() override;
private:
QTableWidget *table;
int row;
int column;
QString content;
};
2.源文件
代码如下(示例):
#include "commands.h"
AddCommand::AddCommand(QTableWidget *tableitem, int row, int column,QString content,QUndoCommand *parent)
: QUndoCommand(parent)
{
this->table = tableitem;
this->row = row;
this->column = column;
this->content = content;
}
//撤销
void AddCommand::undo()
{
table->takeItem(this->row,this->column);
}
//恢复
void AddCommand::redo()
{
table->setItem(this->row,this->column,new QTabelWidgetItem(this->content));
}
对QTableWidget中的单元格填充内容时,如果想撤销,看undo函数,想恢复看redo函数,看完之后,你会发现,撤销不就是删除第row行第column列的单元格吗,恢复就是往第row行第column列里面追加item,对,其实重写QUndoCommand的原理就是这样,撤销就是删除当前操作,恢复就是返回撤销之前的操作,是不是很简单。
三、QUndoStack类
目前QUndoCommand已经重写完了,但是怎么去调用呢,其实在看QUndoCommand类介绍的时候,里面有一句话:QUndoCommand类是存储在QUndoStack上的所有命令的基类,所以在调用QUndoCommand类的时候一定会跟QUndoStack有所关联。
代码如下(示例):
QUndoStack undoStack = new QUndoStack(this);
AddCommand *addCommand = new AddCommand(ui->tableWidget,row,column,str);
undoStack->push(addCommand);
上述代码意思是:声明一个QUndoStack类的对象,然后把重写QUndoCommand类的对象压入QUndoStack中。
四、使用
使用的话,其实就是对QUndoStack类的对象进行操作了。
//撤销
void Widget::on_toolButton_revocation_clicked()
{
int index = undoStack->index();
undoStack->setIndex(index-1);
}
//恢复
void Widget::on_toolButton_reform_clicked()
{
int index = undoStack->index();
undoStack->setIndex(index+1);
}
对QUndoStack的索引值操作,撤销就是对当前索引值减一,恢复对当前的索引值减一,撤销调用undo(),恢复调用redo()。
总结
Qt 的撤销回退事件,最为核心的就是对撤销undo()、恢复redo()的重写,其次就是对QUndoStack的索引值加减,分别调用撤销undo()和恢复redo();