我正在尝试使用QGraphicsPathItem来表示一个带有洞的多边形(想想甜甜圈)。我可以让它正确绘制,中心是透明的。但是,打开项目选择或移动后,我可以在单击孔时与我的对象进行交互。我宁愿将洞视为多边形的一部分。
我做了一些测试,当我检查洞内的一个点时,看起来QPainterPath :: contains()将返回true。我是否需要继承QGraphicsPathItem来实现更具体的contains()函数,还是我还缺少其他东西?
答案 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);
}