PySide2 中的 QGraphicsItem.itemClipsChildrenToShape 问题

安迪·彭德

我正在尝试使用 PySide2 和 PyQtGraph 的组合创建史密斯圆图画布。如上一个问题(Pyqtgraph 剪裁线)中所述,似乎最好的方法是使用QGraphicsEllipseItem绘制外圆,使用QGraphicsPathItem绘制所有内弧QPainterPath,然后将它们添加到外圆并使用ItemClipsChildrenToParent.

这是我的代码:

rline = [0.2, 0.5, 1.0, 2.0, 5.0]
xline = [0.2, 0.5, 1, 2, 5]

circle1 = QGraphicsEllipseItem(-1, -1, 2, 2)
circle1.setPen(mkPen('b', width=0.5))
circle1.setFlag(circle1.ItemClipsChildrenToShape)

pathItem = QGraphicsPathItem()
path = QPainterPath()
path.moveTo(1, 0)

for r in rline:
    raggio = 1./(1+r)
    path.addEllipse(1, -raggio, -raggio*2, raggio*2)

for x in xline:
    path.arcTo(1-x, 0, x*2, x*2, 90, 180)
    path.moveTo(1, 0)
    path.arcTo(1-x, 0, x*2, -x*2, 90, 180)

pathItem.setPath(path)
pathItem.setPen(mkPen('b', width = 0.5))
pathItem.setParentItem(circle1)

我的代码似乎主要工作如下图所示。

在此处输入图片说明

The problem is that the inner arcs aren't quite bound by the outer circle. I would have thought that the clipping should be absolute so that the children cannot draw outside of the parents bounds but maybe this is not the case?

musicamante

pyqtGraph by default creates cosmetic pens, which are pens that always have a width based on the device they're drawn: if you specify a cosmetic pen with a width equal to 0.5, it will always have that size no matter the scale used for the view.

Now, the source of the problem can be found in the documentation about QGraphicsItem.shape(), which specifies:

The outline of a shape can vary depending on the width and style of the pen used when drawing.

Qt cannot know the actual extent of a cosmetic pen (since it completely depends on the paint device, and the same scene can have multiple views, each one with its own transformation. The result is that it computes the shape based on the specified pen width, even if it's cosmetic.

Since you're using very small values, a 0.5 pen width actually becomes very big, and the extent of the shape is hugely augmented by that size, and that's why it seems that the children are not respecting the shape: if you have a 2x2 ellipse, with a pen of 0.5 the resulting shape will be a 2.5x2.5 ellipse (since the extent of the pen is half its width).

解决方案是完全忽略 的默认行为shape(),只使用子类返回椭圆的形状:

class Ellipse(QGraphicsEllipseItem):
    def shape(self):
        path = QPainterPath()
        path.addEllipse(self.rect())
        return path

circle1 = Ellipse(-1, -1, 2, 2)
# ...

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章