使用QT中的命令模式用于FITINVIEW功能
我有 qgraphicsview
,其中包含一些 qgraphicsItem
。此视图具有一些功能,例如 Zoom-In
, Zoom-out
, Fitin
, undo-redo
。<
我的 fitin
功能在 undo-redo
功能中不起作用。
。
使用了命令pattern
class myCommand: public QUndoCommand
{
public:
myCommand();
myCommand(QTransform t, int hr, int vr, QGraphicsView* v);
void undo();
void redo();
QTransform t;
int hScrollBar;
int vScrollBar;
QGraphicsView* mView;
};
(要
myCommand::myCommand(QTransform t, int hr, int vr, QGraphicsView *v)
{
this->t = t;
this->hScrollBar= hr;
this->vScrollBar= vr;
this->mView = v;
}
void myCommand::undo()
{
mView->setTransform(t);
mView->horizontalScrollBar()->setValue(hScrollBar);
mView->verticalScrollBar()->setValue(vScrollBar);
}
void myCommand::redo()
{
myView mv;
mv.FitInView();
}
在qt中
void myView::FitIn()
{
FitInView();
QTransform t = view->transform();
int hrValue = view->horizontalScrollBar()->value();
int vrValue = view->verticalScrollBar()->value();
myCommand* Command1 = new myCommand(t,hrValue,vrValue,view);
undoStack->push(Command1);
}
void myView::DrawDesign()
{
// Logic for inserting all the Rectangles and polylines.
QTimer::singleShot(100, this, [&]() {
FitInView();
});
}
void myView::FitInView()
{
QRectF bounds = scene->sceneRect();
QRectF rect {0,0,200,200};
if (bounds.width() < 200)
{
rect .setWidth(bounds.width());
bounds.setWidth(200);
}
if (bounds.height() < 200)
{
rect.setWidth(bounds.height());
bounds.setHeight(200);
}
view->fitInView(bounds, Qt::KeepAspectRatio);
view->updateGeometry();
}
我
public:
QUndoStack* undoStack;
实现 undo-redo
非常适合我的设计,但它在 undo-redo
功能中不起作用。
我想我在 myCommand :: undo()
和 mycommand :: redo()
函数中犯了一个错误。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
基于您在
因此,所有更改都应在
qundocommand
),ie内部
。将命令推到
,自动执行更改(即qundocommand :: redo
Qundostack
上后,使用 <代码> Qundostack :: pushqcommand :: redo
):创建一个新的
qundocommand
qundocommand :: redo redo
(而不是某个地方) 的步骤别的)。Qundocommand :: undo
中写入此命令的倒数。如果需要,请捕获Qundocommand
构造函数中的初始状态,以轻松恢复Qundocommand :: redo
。应用于您的示例
,因此,
myview :: Fitin
应该执行的唯一动作是在撤消堆栈上推动命令:在REDO命令中实现更改:
因为拟合的逆操作不是唯一的定义,我们将初始状态存储在
Qundocommand
构造函数(能够恢复Qundocommand :: undo
)内部的初始状态: 命令恢复
redo
命令:有用的读取材料:
Based on the many question you posted on the Qt's Undo Framework, it seems to me you are missing an essential part of the Command pattern:
So all changes, should be implemented inside the
QUndoCommand
(follow the link to discover a basic usage example), i.e. insideQUndoCommand::redo
. Once the command is pushed on theQUndoStack
, usingQUndoStack::push
, the change (i.e.QCommand::redo
) is automatically performed:Steps to create a new
QUndoCommand
QUndoCommand::redo
(and not somewhere else).QUndoCommand::undo
. If needed, capture the initial state inside theQUndoCommand
constructor, to easily revertQUndoCommand::redo
.Applied to your example
So, the only action that
myView::FitIn
should perform, is pushing the command on the undo stack:Implement your changes inside the redo command:
As the inverse operation of fitting is not uniquely defined, we store the initial state inside the
QUndoCommand
constructor (to be able to restore the initial state insideQUndoCommand::undo
):Now we can implement the
undo
command to revert theredo
command:Usefull reading material:
QUndoCommand
, including basic code example