【问题标题】:How to enlarge the hover area of a QGraphicsItem如何扩大 QGraphicsItem 的悬停区域
【发布时间】:2012-12-02 12:41:54
【问题描述】:

我有一个带有相当小的点标记的 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。
  • 我不知道我为什么要这样做......
  • 另外,在更正签名后,原来 contains() 没有被调用。即使重新实现 boundingRect() 也无济于事。
  • 通常这些东西是通过边界矩形或形状函数处理的,尝试重载那些
  • 重载 shape() 最终改变了行为。我在文档中找不到任何关于此的具体内容 - 它是否提到了悬停事件使用哪种方法?

标签: qt hover qgraphicsitem


【解决方案1】:

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

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

默认实现调用boundingRect()返回一个简单的 矩形形状,但子类可以重新实现此功能以 为非矩形项目返回更准确的形状。例如,一个 圆形物品可以选择返回椭圆形状以获得更好的碰撞 检测。例如:

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

此函数由 contains() 的默认实现调用 和碰撞路径()。

所以基本上发生的是所有想要访问与项目关联的“区域”的函数,调用形状然后执行例如与生成的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;
}

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

【讨论】:

  • 我不清楚调用 QGraphicsItem 的哪个方法来确定项目的“区域”。从文档中可以看出,它可能是 contains()、boundingBox() 或 shape()。但是,您的回答很有帮助,但正是您对我的问题的评论才有所作为。
  • 很高兴我能帮上忙。只是为了澄清:如果形状没有重载做某事,形状通常会调用边界框。 else 和 shap 本身被各种想要获得项目尺寸概念的函数使用(我同意文档在这方面很差)
  • 另外:如果您发现评论或答案有帮助,您应该点赞,如果完整,请接受。不仅作为代表奖励,而且主要是向其他用户表明它帮助您解决了您的问题,因此也可能对他们有所帮助
  • 我知道,但忘记了 - 感谢您的提醒。请考虑将您在第一条评论中提供的信息(我也赞成)添加到您的答案中。
猜你喜欢
  • 1970-01-01
  • 2011-02-01
  • 2016-01-04
  • 2015-05-24
  • 1970-01-01
  • 2013-03-07
  • 1970-01-01
  • 1970-01-01
  • 2017-01-29
相关资源
最近更新 更多