Qt撤消/重做移动项目

时间:2014-10-15 10:48:06

标签: qt qgraphicsitem undo-redo

我正在我的图形场景中对QGraphicsItemGroup的移动操作实施撤消/重做。它适用于点实体。

我的移动命令如下:

class CommandMove : public QUndoCommand
{
public:
  CommandMove(QGraphicsItemGroup *group, qreal fromX, qreal fromY,
                 qreal toX, qreal toY)
  {
      itemGroup = group;
      mFrom = QPointF(fromX, fromY);
      mTo = QPointF(toX, toY);
      setText(QString("Point move (%1,%2) -> (%3,%4)").arg(fromX).arg(fromY)
              .arg(toX).arg(toY));
  }

  virtual void undo()
  {
      itemGroup->setPos(mFrom);
  }

  virtual void redo()
  {
      itemGroup->setPos(mTo);
  }

private:
  QGraphicsItemGroup *itemGroup;
  QPointF mFrom;
  QPointF mTo;
};

我的命令被推送到撤销堆栈:

if (item.first->scenePos() != item.second)
    {
        mUndoStack->push(new CommandMove(item.first, item.second.x(),
                                            item.second.y(), item.first->x(),
                                            item.first->y()));
    }

itemQPair定义为:

typedef QPair<QGraphicsItemGroup *, QPointF> item;

对于像线,圆等实体的实现,与点相比需要更多信息。例如,线的起点和终点。如何定义移动实体的命令?

修改

这是我对行的实现:

if (m1)
  {
     start_p = event->scenePos();
     m1 = false;
     m2 = true;
  }
else if (!m1 && m2)
  {
     end_p = event->scenePos();
     m3 = true;
     m2 = false;
  }
if (m3)
  {
     lineItem = new Line(start_p, end_p);
  }

此处eventmousePressEvent

我在哪里使用setPos来设置行的位置?

1 个答案:

答案 0 :(得分:2)

我认为你不应该关心所有项目的特点。您可以实现适用于任何项目或项目组的移动命令。这是您代码的修改版本。

class CommandMove : public QUndoCommand
{
public:
  CommandMove(QGraphicsItem *item, qreal toX, qreal toY)
  {
      mItem = item;
      mFrom = mItem->pos();
      mTo = QPointF(toX, toY);
      setText(QString("Point move (%1,%2) -> (%3,%4)").arg(mFrom.x()).arg(mFrom.y())
              .arg(mTo.x()).arg(mTo,y()));
  }

  virtual void undo()
  {
      mItem->setPos(mFrom);
  }

  virtual void redo()
  {
      mItem->setPos(mTo);
  }

private:
  QGraphicsItem* mItem;
  QPointF mFrom;
  QPointF mTo;
};

我希望这会有所帮助。