Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Selection of lines through mouse click is not sharp in Qt
Forum Updated to NodeBB v4.3 + New Features

Selection of lines through mouse click is not sharp in Qt

Scheduled Pinned Locked Moved Unsolved General and Desktop
14 Posts 4 Posters 1.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JonBJ JonB

    @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)?

    T Offline
    T Offline
    tushu
    wrote on last edited by
    #5

    @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 ?

    JonBJ 1 Reply Last reply
    0
    • T tushu

      @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 ?

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #6

      @tushu
      I'm not at all familiar, never done this sort of thing, so limited point asking me about it. You seem to draw it in DrawPolyline()? So isn't that the information you need for this Line::shape()?

      1 Reply Last reply
      0
      • M Offline
        M Offline
        mchinand
        wrote on last edited by
        #7

        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.

        T 1 Reply Last reply
        1
        • M mchinand

          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.

          T Offline
          T Offline
          tushu
          wrote on last edited by
          #8

          @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));
          
          1 Reply Last reply
          0
          • M Offline
            M Offline
            mchinand
            wrote on last edited by
            #9
            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);
            T 1 Reply Last reply
            0
            • M mchinand
              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);
              T Offline
              T Offline
              tushu
              wrote on last edited by
              #10

              @mchinand Thank you for your reply.
              I have a doubt :

              1. 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.
              2. In shape() , how am I going to access all these points ?
              1 Reply Last reply
              0
              • M Offline
                M Offline
                mchinand
                wrote on last edited by mchinand
                #11

                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.

                JonBJ T 2 Replies Last reply
                1
                • M mchinand

                  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.

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #12

                  @mchinand Yeah that's what I thought too....

                  1 Reply Last reply
                  0
                  • M mchinand

                    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.

                    T Offline
                    T Offline
                    tushu
                    wrote on last edited by tushu
                    #13

                    @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.

                    1 Reply Last reply
                    0
                    • JoeCFDJ Offline
                      JoeCFDJ Offline
                      JoeCFD
                      wrote on last edited by
                      #14

                      you may try to inherit QGraphicsPolygonItem and check some examples out.

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved