2014-10-09 182 views
6

我正在使用鼠标单击绘制一条线。定制边界矩形的形状

painter->drawLine(start_p, end_p); 

线的边界矩形定义为::

QRectF Line::boundingRect() const 
{ 
    // bounding rectangle for line 
    return QRectF(start_p, end_p).normalized(); 
} 

enter image description here

这显示画的线用油漆函数作为线的绘制过程。我得到这个的边界矩形,如图所示:

enter image description here

我希望根据物品的形状有边界RECT,是这样的:enter image description here

如何实现这一目标?

编辑

在选择任何重叠线,所述一个在顶部包围矩形被选择(参见下图)。即使使用setZValue也不适用。 我想通过最小化边界矩形来实现这一点。

enter image description here

+0

这是一个交叉帖子。 :) – 2014-10-09 06:22:23

+1

使用['QGraphicsItem :: shape'](http://qt-project.org/doc/qt-5/qgraphicsitem.html#shape)。 – thuga 2014-10-09 06:24:18

+0

我是新手。你能否提供一些演示代码? – 2014-10-09 06:26:55

回答

-1

您必须绘制自己,如果你想这样的一些东西包围。让Qt使用QRect来定界和定义您的新QRect,这个QRect依赖于前一个QRect的角落,左上角和右下角。例如,如果左上角是(2,2)您的新QRect左上角是(1,2),右上角是(2,1)和...

+0

“如果你想要这样的东西,你必须画出自己的界限”这根本不是真的。 – cmannett85 2014-10-09 06:55:49

+0

减少我的观点并说(这根本不是真的)很简单。如果你能回答这个问题的话。我通过QGraphicsView创建了一个包含所有这些功能的整个项目。如果你没有看到这个东西,你不能说这不是真的。 – QCoder 2014-10-09 07:15:53

+0

我可以回答这个问题,但@thuga在45分钟前的评论中提供了答案,代表是他/她的主张。你的答案是错误的,因为你不需要在设置它们时按顺序绘制边界,你可以重写'QGraphicsItem :: boundingRect()'。此外,边界框轴对齐,因此绘制旋转的矩形将导致实际的边界框变得更大。 – cmannett85 2014-10-09 07:21:37

1

有两个相关功能在你应该感兴趣的QGraphicsItem中。第一个是boundingRect。这个,你可能会意识到是一个包含整个项目的矩形。 Qt使用这种方法来快速计算物品的可见度和简单的物品碰撞。

如果您有长方形的物品,这很棒;你可以在你从QGraphicsItem或QGraphicsObject继承的任何项目中覆盖boundingRect()

如果你有一个不规则的形状,你想做一些事情,比如与一个物品的形状碰撞,那么shape()函数也需要在你的类中重写。

这将返回一个QPainterPath,所以你可以做这样的事情: -

QPainterPath Line::shape() 
{ 
    QRectF rect(start_p, end_p).normalized(); 

    // increase the rect beyond the width of the line 
    rect.adjust(-2, -2, 2, 2); 

    QPainterPath path; 
    path.addRect(rect); 

    return path; // return the item's defined shape 
} 

现在,你可以使用一个画家来绘制形状()的项目,而不是boundingRect()和碰撞将工作如预期。

6

如果您的项目不是矩形形状,或者是旋转的矩形,请使用QGraphicsItem::shape

该功能应返回QPainterPath。您应该能够通过使用QPainterPath::addPolygon来创建您的路径。

这里是一个小例子:

QPainterPath Item::shape() const 
{ 
    QPainterPath path; 
    QPolygon polygon; 
    polygon << QPoint(0, 0); 
    polygon << QPoint(5, 5); 
    polygon << QPoint(width, height); 
    polygon << QPoint(width - 5, height - 5); 
    path.addPolygon(polygon); 

    return path; 
} 

你当然应该计算以不同的方式在路径内贵点,但你明白了吧。现在当你点击一个项目时,如果点击发生在由QPainterPath定义的形状内,它将只会选中它。

如果您需要制作曲线,可以使用cmannett85建议的QPainterPathStroker::createStroke

1

boundingRect总是用来优化场景的绘制过程。所以你在这里没有操纵空间。

但是如果你想改变鼠标交互区域,有shape method。默认情况下,此方法返回从boundingRect方法收到的QPainterPath矩形。
因此,只需重写此方法并提供所需的形状。

QPainterPath YourGraphicsItem::shape() const { 
    static const qreal kClickTolerance = 10; 

    QPointF vec = end_p-start_p; 
    vec = vec*(kClickTolerance/qSqrt(QPointF::dotProduct(vec, vec))); 
    QPointF orthogonal(vec.y(), -vec.x()); 

    QPainterPath result(start_p-vec+orthogonal); 
    result.lineTo(start_p-vec-orthogonal); 
    result.lineTo(end_p+vec-orthogonal); 
    result.lineTo(end_p+vec+orthogonal); 
    result.closeSubpath(); 

    return result; 
}