3

我有一个带有相当小的点标记的 QGraphicsScene。我想扩大这些标记的区域以使拖动更容易。标记是一个十字,距离原点 +/- 2 个像素。我重新实现了

QGraphicsItem::contains(const QPointF & point ) const
{
  return QRectF(-10,-10,20,20);
}

void hoverEnterEvent(QGraphicsSceneHoverEvent* event)
{
  setPen(QPen(Qt::red));
  update();
}

但是标记只有在被光标直接击中时才会变成红色(即使这样也有点挑剔)。如何扩大“悬停区域”?

4

1 回答 1

5

如简短评论中所述:通常这些事情是通过边界矩形或形状函数处理的,请尝试重载它们。查看 QGraphicsItem 下 shape 的 qt 帮助(http://doc.qt.io/qt-4.8/qgraphicsitem.html#shape):

将此项的形状作为局部坐标中的 QPainterPath 返回。该形状用于许多事情,包括碰撞检测、命中测试和 QGraphicsScene::items() 函数。

默认实现调用 boundingRect() 来返回一个简单的矩形形状,但是子类可以重新实现这个函数来为非矩形项返回一个更准确的形状。例如,圆形项目可能会选择返回椭圆形以更好地检测碰撞。例如:

QPainterPath RoundItem::shape() const { QPainterPath 路径;path.addEllipse(boundingRect()); 返回路径;形状的轮廓可以根据绘图时使用的笔的宽度和样式而有所不同。如果你想在项目的形状中包含这个轮廓,你可以使用 QPainterPathStroker 从笔划创建一个形状。

该函数由 contains() 和 collidesWithPath() 的默认实现调用。

所以基本上发生的是所有想要访问与项目关联的“区域”的函数,调用形状,然后对生成的painterpath进行例如包含或碰撞检测。因此,如果您有小物品,您应该扩大形状区域。例如,让我们考虑一条作为您的目标的线,而不是您的形状实现可能如下所示:

QPainterPath Segment::shape() const{
  QLineF temp(qLineF(scaled(Plotable::cScaleFactor)));
  QPolygonF poly;
  temp.translate(0,pen.widthF()/2.0);
  poly.push_back(temp.p1());
  poly.push_back(temp.p2());
  temp.translate(0,-pen.widthF());
  poly.push_back(temp.p2());
  poly.push_back(temp.p1());
  QPainterPath path;
  path.addPolygon(poly);
  return path;
}

笔是段的成员,我用它的宽度来扩大形状区域。但是您也可以采用与对象的实际尺寸有良好关系的其他任何东西。

于 2012-12-02T18:40:01.140 回答