我有一个QGraphicsScene
,我希望用户在其中绘制/移动东西。目前我可以绘制所有我想要的形状(即 [un] 填充矩形和椭圆、直线和立方贝塞尔曲线),派生 QGraphics*Item
。
我也可以实现对这些项目的选择,但我想要某种像素完美选择。例如,即使鼠标不在实际线上,也可以在曲线旁边单击它时选择曲线。同样适用于空矩形或椭圆,单击它们中间的孔也可以选择它们。
这是因为 contains
的工作方式,它不符合我的需要:它主要检查点是否在边界矩形中。 setBoundingRegionGranularity(1)
没有解决任何问题(提一下以防万一)。
我还尝试直接检查该点是否包含在我的项目的 QPainterPath
中,但这给了我相同的结果。
我怎样才能视觉选择我的形状?
目前我看到的唯一解决方案是为我拥有的每个形状重新实现我自己的 contains
函数,但这可能非常复杂,如果可能。
我使用的是 Python 3.3 和 PyQt 5 (.1.1 IIRC),但这与 Qt 框架的关系比语言/绑定(bind)更相关,而且 C++ 中的答案也很好。
最佳答案
QGraphicsPathItem::shape
包含它显示的路径,包括它的内部区域。您期望的行为更像是 QGraphicsPixmapItem
。如果它的 shapeMode
是 QGraphicsPixmapItem::MaskShape
(默认),它的形状将只包含不透明的点。您可能希望在像素图上绘制曲线并在场景中显示该像素图并享受默认行为。您还可以重新定义 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);
请注意,此实现非常慢。谨慎使用。
关于python - QGraphicsScene 中的视觉像素完美选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21780018/