具有孔的QPainterPath的多点聚合

时间:2010-02-21 03:06:43

标签: c++ qt

我正在尝试使用QGraphicsPathItem来表示一个带有洞的多边形(想想甜甜圈)。我可以让它正确绘制,中心是透明的。但是,打开项目选择或移动后,我可以在单击孔时与我的对象进行交互。我宁愿将洞视为多边形的一部分。

我做了一些测试,当我检查洞内的一个点时,看起来QPainterPath :: contains()将返回true。我是否需要继承QGraphicsPathItem来实现更具体的contains()函数,还是我还缺少其他东西?

2 个答案:

答案 0 :(得分:1)

如果您将填充规则从默认值Qt :: OddEvenFill更改为Qt :: WindingFill,您还能看到这个洞吗?我想你将无法看到这个洞。所以这个洞实际上不是你路径上的“物理”洞。如果要表示带孔的多边形,则可能需要对QGraphicsPathItem进行子类化,明确定义最外层路径和孔,并维护不同角色的路径之间的关系。

答案 1 :(得分:-1)

您需要继承QGraphicsPathItem并重新实现shape方法。这是我用一个未填充和填充矩形解决类似问题的方法。这个特例是QGraphicsRectItem的子类。这也对路径宽度进行了一些调整,以便用户更容易点击,实际上是路径周围的缓冲区。

对于填充矩形,返回的形状只是一个矩形,但对于未填充的矩形,它是带有空内部的描边路径。然后,只有当用户拖动边缘而不是中间时,对象才会移动。从文档中弄清楚QPainterPathStroker并不直观,但它实际上非常简单易用。

QPainterPath MyRectItem::shape (void) const
    {
    if (this->brush().style() != Qt::NoBrush)
        {
        return QGraphicsRectItem::shape();
        }

    // The rectangle is unfilled. Create a path outlining the rectangle.

    QPainterPath path;

    QRectF rect = this->rect();

    path.moveTo (rect.topLeft());
    path.lineTo (rect.topRight());
    path.lineTo (rect.bottomRight());
    path.lineTo (rect.bottomLeft());
    path.lineTo (rect.topLeft());

    QPainterPathStroker stroker;

    if (this->pen().style() != Qt::NoPen)
        {
        // For easier selection, increase the pen width to provide a buffer zone
        // around the line where the user can click and still select.

        stroker.setWidth     (this->pen().width() + 20);
        stroker.setCapStyle  (this->pen().capStyle());
        stroker.setJoinStyle (this->pen().joinStyle());
        }

    return stroker.createStroke (path);
    }