如何使用 Qt 中的命令模式撤消重做放大、缩小等功能?
我有一个 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论