Selection of lines through mouse click is not sharp in Qt
-
@tushu said in Selection of lines through mouse click is not sharp in Qt:
if(shape().contains(point))
Will overriding contains() solve my issue ?
bool QGraphicsItem::contains(const QPointF &point) const:
By default, this function calls
shape()
, but you can reimplement it in a subclass to provide a (perhaps more efficient) implementation.So what does your override do/achieve that is any different?
If anything I would have thought virtual QPainterPath QGraphicsItem::shape() const:
The default implementation calls
boundingRect()
to return a simple rectangular shape, but subclasses can reimplement this function to return a more accurate shape for non-rectangular items. For example, a round item may choose to return an elliptic shape for better collision detection. For example:Maybe this is what you need to override (I don't know)?
@JonB I understood the problem exactly.
While selecting any of the overlapping lines, the one with bounding rect on top is selected. And this is the exact my problem.
For that I need to override shape() ( you were right as usual ).
I googled and I got a few code samples.QPainterPath Item::shape() const { QPainterPath path; QPolygon polygon; polygon << QPoint(0, 0); polygon << QPoint(5, 5); polygon << QPoint(width, height); polygon << QPoint(width - 5, height - 5); path.addPolygon(polygon); return path; }
QPainterPath Line::shape() { QRectF rect(start_p, end_p).normalized(); // increase the rect beyond the width of the line rect.adjust(-2, -2, 2, 2); QPainterPath path; path.addRect(rect); return path; // return the item's defined shape }
So here the question is, how will I know start_p, end_p ( starting and ending points of a line ) width, height ?
-
@JonB I understood the problem exactly.
While selecting any of the overlapping lines, the one with bounding rect on top is selected. And this is the exact my problem.
For that I need to override shape() ( you were right as usual ).
I googled and I got a few code samples.QPainterPath Item::shape() const { QPainterPath path; QPolygon polygon; polygon << QPoint(0, 0); polygon << QPoint(5, 5); polygon << QPoint(width, height); polygon << QPoint(width - 5, height - 5); path.addPolygon(polygon); return path; }
QPainterPath Line::shape() { QRectF rect(start_p, end_p).normalized(); // increase the rect beyond the width of the line rect.adjust(-2, -2, 2, 2); QPainterPath path; path.addRect(rect); return path; // return the item's defined shape }
So here the question is, how will I know start_p, end_p ( starting and ending points of a line ) width, height ?
-
Have your sub-classed QGraphicsItem keep track of them. Store the points and/or polygon to a member variable. Then you can use them in your custom shape() method.
@mchinand I am following below approach. So not understanding how to keep remeber co-ordinates in a variables.
QPolygon net; net << QPoint(67,202); net << QPoint(120,202); net<< QPoint(120,67); net <<QPoint(320,67); net <<QPoint(320,202); net <<QPoint(520,202); net <<QPoint(520,67); QPainterPath pPath; pPath.addPolygon(net); MyPoly* _poly = new MyPoly(); _poly->DrawPolyline(pPath); scene->addItem(static_cast<QGraphicsPathItem*>(_poly));
-
class MyPoly : public QGraphicsPathItem { //Q_OBJECT public: explicit MyPoly(); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void DrawPolyline(QPainterPath pPath); private: QPolygon polygon_; };
void MyPoly::DrawPolyline(QPolygon polygon) { polygon_ = polygon; QPainterPath pPath; pPath.addPolygon(polygon); this->setPen(QPen(QColor("red"), 2)); this->setPath(pPath); this->setFlag(QGraphicsItem::ItemIsSelectable); //this->setBoundingRegionGranularity(1.0); this has no effect }
QPolygon net; net << QPoint(67,202); net << QPoint(120,202); net<< QPoint(120,67); net <<QPoint(320,67); net <<QPoint(320,202); net <<QPoint(520,202); net <<QPoint(520,67); MyPoly* _poly = new MyPoly(); _poly->DrawPolyline(net);
-
class MyPoly : public QGraphicsPathItem { //Q_OBJECT public: explicit MyPoly(); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void DrawPolyline(QPainterPath pPath); private: QPolygon polygon_; };
void MyPoly::DrawPolyline(QPolygon polygon) { polygon_ = polygon; QPainterPath pPath; pPath.addPolygon(polygon); this->setPen(QPen(QColor("red"), 2)); this->setPath(pPath); this->setFlag(QGraphicsItem::ItemIsSelectable); //this->setBoundingRegionGranularity(1.0); this has no effect }
QPolygon net; net << QPoint(67,202); net << QPoint(120,202); net<< QPoint(120,67); net <<QPoint(320,67); net <<QPoint(320,202); net <<QPoint(520,202); net <<QPoint(520,67); MyPoly* _poly = new MyPoly(); _poly->DrawPolyline(net);
@mchinand Thank you for your reply.
I have a doubt :- QPolygon has many points ( in above example it has 7 points ) How the polygon gets drawn ? Segment by segment ? Means 1st 2 points are taken QPoint(67,202) and QPoint(120,202) and then line is drawn. Then next 2 points.
- In shape() , how am I going to access all these points ?
-
I thought your code already worked for drawing, is that not the case? I thought you just needed to figure out how to use the same points that are used for drawing the polyline in the custom shape() method as well.
-
I thought your code already worked for drawing, is that not the case? I thought you just needed to figure out how to use the same points that are used for drawing the polyline in the custom shape() method as well.
@mchinand Yes, my code is working for drawing. But all these concept ( QPolygon, QPainterPath, QPainterPathStroker, shape() , boundingRect() are new to me. ) I just learned how to extract points from QPolygon. Qt is new to me. I am learning from taking help from people like you.
Sorry if you get irritated. But this is how the inexperienced people learn.P.S. Just few days ago I learned the concept behind paint() from JonB.