QGraphicsScene中的视觉像素完美选择

时间:2014-02-14 12:55:31

标签: python c++ qt qgraphicsitem qgraphicsscene

我有QGraphicsScene我想让用户绘制/移动东西。目前我可以绘制我想要的所有形状(即[un]填充矩形和椭圆,直线和三次贝塞尔曲线),导出QGraphics*Item

我也可以选择这些项目,但我喜欢某种像素完美选择。例如,即使鼠标不在实线上,也可以选择曲线,同时在曲线旁边单击它。对于空矩形或椭圆也是如此,单击它们中间的孔也可以选择它们。

这是因为contains的工作方式,并且它不符合我的需要:它基本上检查点是否在边界矩形中。 setBoundingRegionGranularity(1)没有解决任何问题(以防万一)。

我还尝试直接检查点是否包含在我的项目的QPainterPath中,但这给了我相同的结果。

如何直观地选择我的形状?

我现在看到的唯一解决方案是为我的每个形状重新实现我自己的contains功能,但这可能相当复杂,如果可能,我真的希望Qt完成此操作

我使用的是Python 3.3和PyQt 5(.1.1 IIRC),但它与Qt框架的关系比语言/绑定更多,而且C ++中的答案也很好。

1 个答案:

答案 0 :(得分:1)

QGraphicsPathItem::shape包含它正在显示的路径,包括其内部区域。您期望的行为更像QGraphicsPixmapItem。如果shapeModeQGraphicsPixmapItem::MaskShape(默认值),则其形状将仅包含不透明点。您可能想要在pixmaps上绘制曲线并在场景中显示像素图并享受默认行为。您还可以重新定义QGraphicsPathItem::shape并实现此行为。工作示例,C ++(可以很容易地适用于Python):

class MyGraphicsPathItem : public QGraphicsPathItem {
public:
  MyGraphicsPathItem() {}
  QPainterPath shape() const {
    QRectF rect = path().boundingRect();
    QImage canvas(rect.size().toSize(), QImage::Format_ARGB32);
    canvas.fill(qRgba(0, 0, 0, 0));
    QPainter painter(&canvas);
    painter.setPen(pen());
    painter.drawPath(path().translated(-rect.topLeft()));
    painter.end();
    QPainterPath result;
    result.addRegion(QPixmap::fromImage(canvas).mask());
    return result.translated(rect.topLeft());
  }
};

用法:

MyGraphicsPathItem* item = new MyGraphicsPathItem();
item->setPath(path);
item->setFlag(QGraphicsItem::ItemIsSelectable);
item->setPen(QPen(Qt::green, 3));
scene->addItem(item);

请注意,此实现速度很慢。请谨慎使用。