如何使用 Qt 中的命令模式撤消重做放大、缩小等功能?

发布于 2025-01-13 02:15:08 字数 2733 浏览 3 评论 0原文

我有一个 QGraphicsView,其中包含矩形、折线、文本等。我​​还有一些转换视图的功能,如放大、缩小、适合视图、更改鼠标右键单击的颜色等。我想添加更多功能如撤消和重做。

撤消意味着,用户应该取消最后执行的命令的效果并 显示之前的转换。所以如果用户做了像缩放这样的转换 在->放大->适合->放大,现在按下撤消然后查看 应显示适合位置。

我尝试过命令模式来实现撤消-重做功能。但我这样做是为了在设计中添加/删除矩形、折线。它起作用了。
HCommand.h

#include <QUndoCommand>
#include<QGraphicsItem>
#include<QGraphicsScene>

class myCommand : public QUndoCommand
{

public:
        HCommand(QGraphicsItem* mItem, QGraphicsScene* scene);
        HCommand(QGraphicsScene* scene, QGraphicsView* mView);// for fitIn

 private:
        QGraphicsItem* mItem;
        QGraphicsScene* mScene;
        QGraphicsView* mView;

        void undo();
        void redo();
};          
    

HCommand.cpp

#include "hcommand.h"

HCommand::HCommand(QGraphicsItem* item, QGraphicsScene* scene):
   mItem(item), mScene(scene)

{}

void HCommand::undo()
{
    if(mItem)
        mScene->removeItem(mItem);
}

void HCommand::redo()
{
    if(mItem)
        mScene->addItem(mItem);
}
              

Widget.h

class Widget : public QGraphicsView
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    Rectangle r;
    PolyLine p;
    QUndoStack* undoStack;
    void undo();
    void redo();
private:
    Ui::Widget *ui;
    QGraphicsScene* scene;
    QGraphicsView* view;
}     

Widget.cpp

Widget::Widget(QWidget *parent)
    : QGraphicsView(parent)
    , ui(new Ui::Widget)
{     
    ui->setupUi(this);
    scene = new QGraphicsScene(this);
    view = new QGraphicsView(this);    
    view->setScene(scene);
    undoStack = new QUndoStack(this);
    ui->verticalLayout_2->addWidget(view);       
}          
void Widget::undo()
{
    undoStack->undo();
}

void Widget::redo()
{
    undoStack->redo();
}       
void Widget::on_schematicBtn_clicked()
{
    QGraphicsRectItem* in = r.createRect(20,160,20,20);
    scene->addItem(in);
    HCommand* com = new HCommand(in,scene);
    undoStack->push(com);        
    // many rectangles and polyline code, same as above     
}       
   

但现在我想对放大、缩小、缩小进行撤消-重做。但每当我放大/缩小时,我都会放大/缩小全视图

void Widget::on_zoomIn_clicked()
{
    double sFactor = 1.2;
    view->scale(sFactor,sFactor);
}


void Widget::on_zoomOut_clicked()
{
    double sFactor = 1.2;
    view->scale(1/sFactor,1/sFactor);
}         
 
void Widget::on_fitInBtn_clicked()
{
    view->resetTransform();
}

所以问题是:

在上面的代码中,我将特定的矩形推入堆栈中,以便进行缩放 输入/输出如何将完整视图推入堆栈?这样以后我就可以拉它 从堆栈中取出?或者这可以以不同的方式实现?

任何帮助表示赞赏。

I have a QGraphicsView, which contains rectangle, polyline, text etc. I also have some features to transform the view like zoom in, zoom out, Fit in view, change the color on mouse right click etc. I want to add few more features like Undo and Redo.

Undo means, user should cancel the effect of last command executed and
show previous transformation. So If user did transformation like zoom
in -> zoom in -> fit in -> zoom in and now pressed Undo then view's
fit in position should get displayed.

I have tried Command pattern to implement Undo-Redo feature. But I did it to add/remove rectangle,polyline in design. And it worked.
HCommand.h

#include <QUndoCommand>
#include<QGraphicsItem>
#include<QGraphicsScene>

class myCommand : public QUndoCommand
{

public:
        HCommand(QGraphicsItem* mItem, QGraphicsScene* scene);
        HCommand(QGraphicsScene* scene, QGraphicsView* mView);// for fitIn

 private:
        QGraphicsItem* mItem;
        QGraphicsScene* mScene;
        QGraphicsView* mView;

        void undo();
        void redo();
};          
    

HCommand.cpp

#include "hcommand.h"

HCommand::HCommand(QGraphicsItem* item, QGraphicsScene* scene):
   mItem(item), mScene(scene)

{}

void HCommand::undo()
{
    if(mItem)
        mScene->removeItem(mItem);
}

void HCommand::redo()
{
    if(mItem)
        mScene->addItem(mItem);
}
              

Widget.h

class Widget : public QGraphicsView
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    Rectangle r;
    PolyLine p;
    QUndoStack* undoStack;
    void undo();
    void redo();
private:
    Ui::Widget *ui;
    QGraphicsScene* scene;
    QGraphicsView* view;
}     

Widget.cpp

Widget::Widget(QWidget *parent)
    : QGraphicsView(parent)
    , ui(new Ui::Widget)
{     
    ui->setupUi(this);
    scene = new QGraphicsScene(this);
    view = new QGraphicsView(this);    
    view->setScene(scene);
    undoStack = new QUndoStack(this);
    ui->verticalLayout_2->addWidget(view);       
}          
void Widget::undo()
{
    undoStack->undo();
}

void Widget::redo()
{
    undoStack->redo();
}       
void Widget::on_schematicBtn_clicked()
{
    QGraphicsRectItem* in = r.createRect(20,160,20,20);
    scene->addItem(in);
    HCommand* com = new HCommand(in,scene);
    undoStack->push(com);        
    // many rectangles and polyline code, same as above     
}       
   

But now I want to do Undo-Redo for Zoom In , Zoom Out, Fit In. But whenever I zoom in/out, I zoomed in/out full view

void Widget::on_zoomIn_clicked()
{
    double sFactor = 1.2;
    view->scale(sFactor,sFactor);
}


void Widget::on_zoomOut_clicked()
{
    double sFactor = 1.2;
    view->scale(1/sFactor,1/sFactor);
}         
 
void Widget::on_fitInBtn_clicked()
{
    view->resetTransform();
}

So the question is :

In above code I am pushing particular rectangle in stack so for zoom
in/out how to push full view in stack ? So that, later I can pull it
out from stack ? Or this can be implemented differently ?

Any help is appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文