我有QGraphicsScene
我想让用户绘制/移动东西。目前我可以绘制我想要的所有形状(即[un]填充矩形和椭圆,直线和三次贝塞尔曲线),导出QGraphics*Item
。
我也可以选择这些项目,但我喜欢某种像素完美选择。例如,即使鼠标不在实线上,也可以选择曲线,同时在曲线旁边单击它。对于空矩形或椭圆也是如此,单击它们中间的孔也可以选择它们。
这是因为contains
的工作方式,并且它不符合我的需要:它基本上检查点是否在边界矩形中。 setBoundingRegionGranularity(1)
没有解决任何问题(以防万一)。
我还尝试直接检查点是否包含在我的项目的QPainterPath
中,但这给了我相同的结果。
如何直观地选择我的形状?
我现在看到的唯一解决方案是为我的每个形状重新实现我自己的contains
功能,但这可能相当复杂,如果可能,我真的希望Qt完成此操作
我使用的是Python 3.3和PyQt 5(.1.1 IIRC),但它与Qt框架的关系比语言/绑定更多,而且C ++中的答案也很好。
答案 0 :(得分:1)
QGraphicsPathItem::shape
包含它正在显示的路径,包括其内部区域。您期望的行为更像QGraphicsPixmapItem
。如果shapeMode
为QGraphicsPixmapItem::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);
请注意,此实现速度很慢。请谨慎使用。