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

Posted

技术标签:

【中文标题】QGraphicsItem 移动事件 - 获取绝对位置【英文标题】:QGraphicsItem move event - get absolute position 【发布时间】:2014-02-28 14:36:07 【问题描述】:

我有一个QGraphicsEllipseItem,我希望它可以移动并在移动时触发信号。 所以我将QGraphicsEllipseItemQObject 子类化并覆盖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 几乎相等,但包含相对于运动开始的坐标。

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

【问题讨论】:

【参考方案1】:

这不是错误,这是标准行为。

构造函数要求 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) 显式设置位置可以解决问题。

我真的很想知道这是这种行为的意图。文档没有给出任何提示。

【讨论】:

这实际上是一个记录在案的行为:你传入构造函数的是椭圆的几何坐标,而不是QGraphicsEllipseItempos椭圆的几何由rect定义 , 并且它的笔和画笔被初始化为笔和画笔。请注意,项目的几何图形以项目坐标提供,其位置初始化为 (0, 0)。 构造函数中的坐标定义了省略号的偏移量。这对于将省略号置于其自身中心非常方便。我同意我也对这种行为感到惊讶,但它实际上很方便

以上是关于QGraphicsItem 移动事件 - 获取绝对位置的主要内容,如果未能解决你的问题,请参考以下文章

Qt 视图框架QGraphicsItem

QGraphicsItem 鼠标中按事件

为啥所有选中的 QGraphicsItem 都没有收到 mouseMove 事件?

将鼠标事件从 QGraphicsItem 传递给 QGraphicsScene

创建自定义 QGraphicsItem 时拦截鼠标事件

使用 mouseMoveEvent 约束 QGraphicsItem 移动