Qt 的撤銷回退事件

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();

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章