QGraphicsItem::shape() seems partially ignored for click hit.
-
Hello all,
I'm using a QGraphicsItemGroup to represent an arc on a QGraphicsScene.
I want this arc to be selectable by user when clicking on it, or near it. The idea is to make the arc itself clickable, as well as a small strip around the arc.To to do, I use QGraphicsItem::shape() to return a shape corresponding to the area I want to be clickable.
The shape object is also used for an other purpose: to display a dotted box indicating the object is selected (overriding the default selection box).The code to generate the shape is as follows, with "arrowPath" being the arc path itself:
QPainterPath arrowPath = ((QGraphicsPathItem*)arrowBody)->path(); path.moveTo(0, this->middleBarLength/2); path.lineTo(0, -this->middleBarLength/2); arrowPath.translate(0, -this->middleBarLength/2); path.connectPath(arrowPath); path.lineTo(arrowPath.boundingRect().width(), this->middleBarLength/2); arrowPath.translate(0, this->middleBarLength); arrowPath = arrowPath.toReversed(); path.connectPath(arrowPath); path.closeSubpath(); QTransform t; t.rotate(-sceneAngle); this->boundingShape = t.map(path);
What I do is as follows:
- Draw a vertical line (bottom up),
- Translate the arc path to the end position and link it,
- Draw another vertical line (top down),
- Reverse the arc path, translate it to the end position and link it,
- Close the path,
- Rotate the shape to match the arc rotation.
The shape() function then just returns the boundingShape object, which is updated on any change on the shape.
This makes a correct shape when I display the selection box.But the problem occurs as follows: while the shape seems to be respected for the outter shape (clicking outside the shape on the convex side does not select it), it is not OK for the inner shape: clicking outside the shape, on the concave side, in a place that is between two points of the arc DOES select it. I'm not sure I'm very clear on my explanations, I hope you see what I mean.
Problem is I can have various arcs, with different radius of curvature, but with the same origin/target. All being on the same Z stacking order, the incorrect arc can be selected. I can't define a different Z position without major modification to my code.
A funny thing is: i can work around this issue by adding a specific check on click:
mousePressEvent(QGraphicsSceneMouseEvent* ev) { if ( ! this->boundingShape.contains(ev->pos()) ) ev->ignore(); }
But I don't understand why I have to do this, and this could potentially be harmful because I can't implement the mouse release, double click and move function without breaking this behavior.
So if anyone has a hint on what's happening, I would be very thankful.