Qt QGraphicsItem移动事件-获取绝对位置

Qt QGraphicsItem移动事件-获取绝对位置,qt,draggable,qtgui,Qt,Draggable,Qtgui,我有一个QGraphicsEllipseItem,我想移动它,并在移动时触发信号。 因此,我将QGraphicsEllipseItem和QObject子类化,并重写itemChange方法以触发信号。这一切似乎都可行,但报告的位置似乎与项目的旧位置相关。即使询问项目的位置似乎只是检索相对坐标 下面是一些代码来说明我所做的工作: class MyGraphicsEllipseItem: public QObject, public QGraphicsEllipseItem { Q_OBJECT

我有一个
QGraphicsEllipseItem
,我想移动它,并在移动时触发信号。 因此,我将
QGraphicsEllipseItem
QObject
子类化,并重写
itemChange
方法以触发信号。这一切似乎都可行,但报告的位置似乎与项目的旧位置相关。即使询问项目的位置似乎只是检索相对坐标

下面是一些代码来说明我所做的工作:

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
}
这是项创建过程:

  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);
和插槽:

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()));
}
void主窗口::on_itemMoved(QPointF p)
{
MyGraphicsSellipseitem*el=动态强制转换(QObject::sender());
QPointF newPos=el->scenePos();
scalebl->setText(QString((%1,%2)-(3,%4)”).arg(newPos.x()).arg(newPos.y()).arg(p.x()).arg(p.y());
}
奇怪的是
newpos
p
几乎相等,但包含相对于运动开始的坐标

如何获取被拖动对象的当前位置?还有别的方法可以达到这个目标吗?

我找到了原因: 构造函数
QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x,qreal y,qreal width,qreal height,QGraphicsItem*parent=0)
未按预期工作。在使用一些x和y调用它之后,该项仍然报告0,0作为其位置。将0,0赋给构造函数,并使用
setPos(x,y)
显式设置位置解决了这个问题


我真想知道这就是这种行为的用意。文档对此没有任何提示。

这不是一个bug,而是标准行为

构造函数要求使用QRectF来确定椭圆及其大小和原点。两种常用的尺寸是(0,0,宽度,高度)(原点位于左上方)和(-0.5*宽度,-0.5*高度,宽度,高度)(原点位于中心)


使用
setPos
,原点被设置在所需的位置。

这实际上是一个有文档记录的行为:您在构造函数中传递的是椭圆的几何坐标,而不是
QGraphicsSellipseitem
pos
:椭圆的几何体由rect定义,其画笔和画笔被初始化为画笔和画笔。请注意,项目的几何图形在项目坐标中提供,其位置初始化为(0,0)。构造函数中的坐标定义省略号的偏移。这是非常方便的中心省略号自己的中心。我同意我也对这种行为感到惊讶,但实际上这很方便