Qt 的撤銷回退事件
日期 | 作者 | 版本 |
---|---|---|
2020年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();