Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QGraphicsItem move event - get absolute position

I have a QGraphicsEllipseItem that I want to be movable and triggering signals on moving. So I subclassed QGraphicsEllipseItem and QObject and overrode the itemChange method to trigger a signal. That all seems to work but the positions that are reported seem to be relative to the old position of the item. Even if asking the item for its position seems only to retrieve the relative coordinates.

Here is some code to make clear what I have done:

class MyGraphicsEllipseItem: public QObject, public QGraphicsEllipseItem
{
  Q_OBJECT

public:

  MyGraphicsEllipseItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0, QGraphicsScene *scene = 0)
    :QGraphicsEllipseItem(x,y,w,h, parent, scene)
  {}

  QVariant itemChange(GraphicsItemChange change, const QVariant &value);

signals:
  void itemMoved(QPointF p);
};

QVariant MyGraphicsEllipseItem::itemChange( GraphicsItemChange change, const QVariant  &value )
{ 
  // value seems to contain position relative start of moving
  if (change == ItemPositionChange){
    emit itemMoved(value.toPointF());
  }
  return QGraphicsEllipseItem::itemChange(change, value); // i allso tried to call this before the emiting
}

this is the item creation:

  MyGraphicsEllipseItem* ellipse = new MyGraphicsEllipseItem(someX, someY, someW, someH);
  ellipse->setFlag(QGraphicsItem::ItemIsMovable, true);
  ellipse->setFlag(QGraphicsItem::ItemSendsScenePositionChanges, true);
  connect(ellipse, SIGNAL(itemMoved(QPointF)), SLOT(on_itemMoved(QPointF)));
  graphicsView->scene()->addItem(ellipse);

and the slot:

void MainWindow::on_itemMoved( QPointF p)
{
  MyGraphicsEllipseItem* el = dynamic_cast<MyGraphicsEllipseItem*>(QObject::sender());
  QPointF newPos = el->scenePos();
  scaleLbl->setText(QString("(%1, %2) - (%3, %4)").arg(newPos.x()).arg(newPos.y()).arg(p.x()).arg(p.y()));
}

The strange thing is that newpos and p are almost equal but contain coordinates relative to the beginning of the movement.

How do I get the current position of the dragged object? Is there another way to achieve the goal?

like image 639
vlad_tepesch Avatar asked Feb 04 '14 14:02

vlad_tepesch


2 Answers

It's not a bug, it is standard behavior.

The constructor asks for a QRectF to determine the ellipse its size and its origin. Two commonly used sizes are (0,0,width,height) (origin at topleft) and (-0.5 * width, -0.5 * height, width, height) (origin at center).

With setPos, that origin is set at the desired position.

like image 86
richelbilderbeek Avatar answered Nov 05 '22 00:11

richelbilderbeek


I found the reason: the constructor QGraphicsEllipseItem::QGraphicsEllipseItem ( qreal x, qreal y, qreal width, qreal height, QGraphicsItem * parent = 0 ) does not work as expected. after calling it with some x and y the item still reports 0,0 as its position. giving 0,0 to constructor and explicitly setting position with setPos(x,y) solves the thing.

I really wonder that was the intention for this behaviour. The documentation gives no hint for this.

like image 39
vlad_tepesch Avatar answered Nov 05 '22 01:11

vlad_tepesch