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

6
我有一个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()));
}

奇怪的是,newposp几乎相等,但都包含相对于移动开始位置的坐标。

如何获取拖动对象的当前位置?还有其他方法可以实现这个目标吗?

2个回答

6

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

构造函数要求一个QRectF来确定椭圆的大小和起点。两个常用的大小是(0,0,width,height)(左上角为原点)和(-0.5 * width, -0.5 * height, width, height)(中心为原点)。

使用setPos,可以将原点设置在所需位置。


2
我找到了原因:构造函数QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = 0)不像预期那样工作。在使用一些x和y调用后,该项仍然报告其位置为0,0。将0,0传递给构造函数并使用setPos(x,y)显式设置位置可以解决问题。
我真的很想知道这种行为的意图是什么。文档没有提供任何提示。

1
这实际上是一种记录下来的行为:构造函数中传递的是椭圆的几何坐标,而不是QGraphicsEllipseItempos:椭圆的几何形状由矩形定义,其笔和刷被初始化为给定的笔和刷。请注意,该项的几何形状以项坐标提供,并且其位置初始化为(0,0)。 - kambala
1
构造函数中的坐标定义省略号的偏移量。这非常方便,可以将省略号居中在其自身的中心位置。我同意,我也对这种行为感到惊讶,但实际上它非常方便。 - Overdrivr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接