Qt撤销/回撤框架

想必大家都有这样的需求:Ctrl+Z、Ctrl+Y进行用户操作的撤销和回撤,Qt框架中有Qt's Undo Framework供大家使用。

该框架由四个类组成:
QUndoCommand:是存储在撤销堆栈上的所有命令的基类。它可以应用(重做)或撤销文档中的单个更改。
QUndoStack:是一组QUndoCommand。它包含了在文档上执行的所有命令,并可以通过撤消或重做它们来前后滚动文档的状态。
QUndoGroup:是一组QUndoStack。当应用程序包含多个QUndoStack时,它很有用,通常是每个打开的文档一个堆栈。QUndoGroup为组中的所有堆栈提供了一对撤销/重做槽。它将撤消和重做请求转发到活动堆栈,活动堆栈是与用户当前正在编辑的文档相关联的堆栈。
QUndoView:是一个显示撤销堆栈内容的小部件。单击视图中的命令会将文档的状态向后滚动或转发到该命令。

那么我们来看看怎么使用该框架吧!

step0:准备工作,添加快捷键等;

step1:继承QUndoCommand类并实现undo()、redo()方法;

step2:在操作的地方,创建一个QUndoCommand实例,并且push进QUndoStack,此时会自动调用Command的redo()方法;

step3:想撤销时,Ctrl+Z会调用undo()方法;

---------------------------------------------------------------------------------------------------------------------------------step0:

    undoAction = undoStack->createUndoAction(this, tr("&Undo"));
    undoAction->setShortcuts(QKeySequence::Undo);

    redoAction = undoStack->createRedoAction(this, tr("&Redo"));
    redoAction->setShortcuts(QKeySequence::Redo);

step1:

class AddCommand : public QUndoCommand
{
public:
    AddCommand(DiagramItem::DiagramType addType, QGraphicsScene *graphicsScene,
               QUndoCommand *parent = 0);
    ~AddCommand();

    void undo() override;
    void redo() override;

private:
    DiagramItem *myDiagramItem;
    QGraphicsScene *myGraphicsScene;
    QPointF initialPosition;
};

AddCommand::AddCommand(DiagramItem::DiagramType addType,
                       QGraphicsScene *scene, QUndoCommand *parent)
    : QUndoCommand(parent)
{
    static int itemCount = 0;

    myGraphicsScene = scene;
    myDiagramItem = new DiagramItem(addType);
    initialPosition = QPointF((itemCount * 15) % int(scene->width()),
                              (itemCount * 15) % int(scene->height()));
    scene->update();
    ++itemCount;
    setText(QObject::tr("Add %1")
        .arg(createCommandString(myDiagramItem, initialPosition)));
}

AddCommand::~AddCommand()
{
    if (!myDiagramItem->scene())
        delete myDiagramItem;
}

void AddCommand::undo()
{
    myGraphicsScene->removeItem(myDiagramItem);
    myGraphicsScene->update();
}

void AddCommand::redo()
{
    myGraphicsScene->addItem(myDiagramItem);
    myDiagramItem->setPos(initialPosition);
    myGraphicsScene->clearSelection();
    myGraphicsScene->update();
}

step2:

    QUndoCommand *addCommand = new AddCommand(DiagramItem::Box, diagramScene);
    undoStack->push(addCommand);

step3:

试一试按下Ctrl+Z组合键?

P.S.

使用QUndoView进行命令记录:

    undoView = new QUndoView(undoStack);
    undoView->setWindowTitle(tr("Command List"));
    undoView->show();
    undoView->setAttribute(Qt::WA_QuitOnClose, false);

你可能感兴趣的:(Qt,qt,开发语言)