title: How to perform swap of QGraphicsItem(s) in QGraphicsView?
body: <p>My idea in this project is to perform swap animation on items.
  Problem is however that when I perform swap on items for the first time they keep their position still, but when the other animation starts that involves already swapped items, those items fall back to their initial positions. Please tell me what am I doing wrong. Animation as follows: </p>
  
  <p><a href="https://i.stack.imgur.com/r3Px2.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/r3Px2.gif" alt="enter image description here"></a></p>
  
  <pre><code>    #include &lt;QtCore&gt;
      #include &lt;QtWidgets&gt;
  
  
      /**
       * Element to be displayed in QGraphicsView
       */
      class QGraphicsRectWidget : public QGraphicsWidget
      {
          Q_OBJECT
          int m_number;
  
      public:
  
          void changePosition(QGraphicsRectWidget *other)
          {
              setPos(mapToParent(other-&gt;x() &lt; x() ? -abs(x() - other-&gt;x())
                                                        : abs(x() - other-&gt;x()) ,0));
          }
  
          static int NUMBER;
  
          QGraphicsRectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent), m_number(NUMBER)
          { NUMBER++;}
          void paint(QPainter *painter, const QStyleOptionGraphicsItem *,
                     QWidget *) Q_DECL_OVERRIDE
          {
              painter-&gt;fillRect(rect(), QColor(127, 63, 63));
              painter-&gt;drawText(rect(), QString("%1").arg(m_number), QTextOption(Qt::AlignCenter));
          }
  
      };
  
      int QGraphicsRectWidget::NUMBER = 1;
  
  
      class MyAnim : public QPropertyAnimation
      {
          Q_OBJECT
  
          QGraphicsView &amp;pview;   // View in which elements must be swapped   
          int i1, i2;         // Indices for elements to be swapped
  
      public:
          MyAnim(QGraphicsView &amp;view, int index1 = 0, int index2 = 1, QObject *par = 0)
              : QPropertyAnimation(par), pview(view), i1(index1), i2(index2)
          {
              QObject::connect(this, SIGNAL(finished()), SLOT(slotOnFinish()));
          }
  
      public slots:
          /* !!!!!!!!!!!!!!!!!!!!!!! HERE IS THE PROBLEM (brobably)   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
          // Triggered when animation is over and sets position of target element to position of its end value
          void slotOnFinish()
          {
              auto list = pview.items();
  
              static_cast&lt;QGraphicsRectWidget*&gt;(list.at(i1))
                      -&gt;changePosition(static_cast&lt;QGraphicsRectWidget*&gt;(list.at(i2)));
          }
      };
  
      class GraphicsView : public QGraphicsView
      {
          Q_OBJECT
      public:
          GraphicsView(QGraphicsScene *scene, QWidget *parent = NULL) : QGraphicsView(scene, parent)
          {
          }
  
      protected:
          virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE
          {
              fitInView(scene()-&gt;sceneRect());
              QGraphicsView::resizeEvent(event);
          }
      };
  
  
      #define SWAP_HEIGHT 75
  
      /**
       * Creates swap animation for items in QGraphicsView 
       */
      QParallelAnimationGroup* getSwapAnimation(QGraphicsView &amp;view, int noItem1, int noItem2)
      {
          auto list = view.items();
          QGraphicsRectWidget *wgt1 = static_cast&lt;QGraphicsRectWidget*&gt;(list.at(noItem1));
          QGraphicsRectWidget *wgt2 = static_cast&lt;QGraphicsRectWidget*&gt;(list.at(noItem2));
  
          MyAnim *pupperAnim, *plowerAnim;
          QParallelAnimationGroup *par = new QParallelAnimationGroup;
  
          plowerAnim = new MyAnim(view, noItem1, noItem2);
          plowerAnim-&gt;setTargetObject(wgt2);
          plowerAnim-&gt;setPropertyName("pos");
          plowerAnim-&gt;setDuration(5000);
          plowerAnim-&gt;setKeyValueAt(1.0/3.0, QPoint(wgt2-&gt;x(), wgt1-&gt;y() - SWAP_HEIGHT));
          plowerAnim-&gt;setKeyValueAt(2.0/3.0, QPoint(wgt1-&gt;x(), wgt1-&gt;y() - SWAP_HEIGHT));
          plowerAnim-&gt;setEndValue(wgt1-&gt;pos());
  
  
          pupperAnim = new MyAnim(view, noItem2, noItem1);
          pupperAnim-&gt;setTargetObject(wgt1);
          pupperAnim-&gt;setPropertyName("pos");
          pupperAnim-&gt;setDuration(5000);
          pupperAnim-&gt;setKeyValueAt(1.0/3.0, QPoint(wgt1-&gt;x(), wgt2-&gt;y() + SWAP_HEIGHT));
          pupperAnim-&gt;setKeyValueAt(2.0/3.0, QPoint(wgt2-&gt;x(), wgt2-&gt;y() + SWAP_HEIGHT));
          pupperAnim-&gt;setEndValue(wgt2-&gt;pos());
  
          par-&gt;addAnimation(pupperAnim);
          par-&gt;addAnimation(plowerAnim);
          return par;
      }
  
      int main(int argc, char **argv)
      {
          QApplication app(argc, argv);
  
          QGraphicsRectWidget *button1 = new QGraphicsRectWidget;
          QGraphicsRectWidget *button2 = new QGraphicsRectWidget;
          QGraphicsRectWidget *button3 = new QGraphicsRectWidget;
          QGraphicsRectWidget *button4 = new QGraphicsRectWidget;
          button2-&gt;setZValue(1);
          button3-&gt;setZValue(2);
          button4-&gt;setZValue(3);
          QGraphicsScene scene(0, 0, 300, 300);
          scene.setBackgroundBrush(QColor(23, 0, 0));
          scene.addItem(button1);
          scene.addItem(button2);
          scene.addItem(button3);
          scene.addItem(button4);
          GraphicsView window(&amp;scene);
          window.setFrameStyle(0);
          window.setAlignment(Qt::AlignLeft | Qt::AlignTop);
          window.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
          window.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  
  
          QList&lt;QGraphicsItem*&gt; items = window.items();
          QPoint start(20, 125);
  
          for (auto item : items) // Set items in initial position
          {
              QGraphicsWidget *wgt = static_cast&lt;QGraphicsWidget*&gt;(item);
              wgt-&gt;resize(50,50);
              wgt-&gt;moveBy(start.x(), start.y());
              start.setX(start.x() + 70);
          }
  
  
          QSequentialAnimationGroup gr;
  
          gr.addAnimation(getSwapAnimation(window, 0, 1));
          gr.addAnimation(getSwapAnimation(window, 1, 2));
          gr.addAnimation(getSwapAnimation(window, 2, 3));
          gr.addAnimation(getSwapAnimation(window, 3, 1));
          gr.start();
  
          window.resize(300, 300);
          window.show();
  
          return app.exec();
      }
  
      #include "main.moc"
  </code></pre>
  
  <p>UPD: Don't use animation with that purpose</p>
  
  <p>UPD*: Forget previous UPD</p>