如何扩大QGraphicsItem的悬停区域

3

我有一个QGraphicsScene,并且其中有相当小的点标记。我希望扩大这些标记的区域,以使拖动更容易。该标记是十字形的,距原点+/- 2像素。我已经重新实现了

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

并且

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

但是只有当光标直接命中标记时,标记才会变红(即使如此也有点挑剔)。 我该如何扩大“悬停区域”?


QGraphicsItem::contains() 需要返回一个布尔值。而你却返回了一个 QRectF。 - Stephen Chu
我不知道我为什么要这样做... - Christoph
此外,事实证明,在修正签名后并不会调用contains()。即使重新实现boundingRect()也没有帮助。 - Christoph
1
通常这些事情是通过边界矩形或形状函数处理的,尝试重载它们。 - Martin
重载shape()最终改变了行为。我在文档中找不到具体的信息 - 它是否提到哪种方法用于悬停事件? - Christoph
1个回答

5
通常情况下,这些事情可以通过边界矩形或形状函数来处理,尝试重载它们。请查看Qt帮助中QGraphicsItem的shape部分(https://doc.qt.io/qt-6/qgraphicsitem.html#shape)。

Returns the shape of this item as a QPainterPath in local coordinates. The shape is used for many things, including collision detection, hit tests, and for the QGraphicsScene::items() functions.

The default implementation calls boundingRect() to return a simple rectangular shape, but subclasses can reimplement this function to return a more accurate shape for non-rectangular items. For example, a round item may choose to return an elliptic shape for better collision detection. For example:

QPainterPath RoundItem::shape() const {
    QPainterPath path;
    path.addEllipse(boundingRect());
    return path; }

The outline of a shape can vary depending on the width and style of the pen used when drawing. If you want to include this outline in the item's shape, you can create a shape from the stroke using QPainterPathStroker.

This function is called by the default implementations of contains() and collidesWithPath().

所以基本上发生的情况是,所有想要访问与项目相关联的“区域”的函数都会调用shape,然后使用生成的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;
}

笔是段落的一部分,我使用它的宽度来扩大形状区域。但你也可以选择其他与你物体的实际尺寸有良好关联的东西。


我不清楚QGraphicsItem的哪个方法被调用来确定物品的“区域”。根据文档所说,它可能是contains(),boundingBox()或shape()。然而,你的回答相当有帮助,但正是你对我的问题的评论产生了影响。 - Christoph
很高兴能够帮忙。只是为了澄清:如果Shape没有被重载做其他事情,它通常会调用bounding box。而shap本身被各种想要获取物品尺寸概念的函数使用(我同意文档在这方面相当贫乏)。 - Martin
此外:如果您发现某个评论或答案有帮助,应该点赞并接受它。这不仅是为了获得声望奖励,更重要的是向其他用户表明它对您的问题有所帮助,因此也可能对他们有所帮助。 - Martin
我知道,但是忘记了 - 感谢您的提醒。请考虑将您在第一条评论中提供的信息(我也点赞了)添加到您的答案中。 - Christoph

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