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. How to pass mouse clicked co-ordinates got through QMouseEvent to different class in Qt?
Forum Updated to NodeBB v4.3 + New Features

How to pass mouse clicked co-ordinates got through QMouseEvent to different class in Qt?

Scheduled Pinned Locked Moved Unsolved General and Desktop
18 Posts 4 Posters 867 Views 2 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.
  • mrjjM mrjj

    @tushu
    Hi
    WidgetPTR means a pointer to an instance of Widget class.
    If you use Mypoly in the Widget class, then you can just use "this" for the pointer.

    • But in code, there are many object of MyPoly
      Do you want all of them to get the same QPointF ? (mouseCurrentPosition)
      If yes, you need to hook them up when you create them then they all get the signal.
      If think you create new Poly in

    void Widget::on_schematicButoon_clicked()

    Is that the place ?

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

    @mrjj
    Yes, I want to create mouseCurrentPosition like global variable. So that everyone ( every MyPoly object ) can access it.

    I have created new Poly in
    void Widget::on_schematicButoon_clicked()
    and I tried like this

    void Widget::on_schematicButoon_clicked()
    {
        QPolygon net0;
        net0 << QPoint(50,180);
        net0 << QPoint(600,180);
        MyPoly* _poly0 = new MyPoly();
        _poly0->DrawPolyline(net0);
        scene->addItem(static_cast<QGraphicsPathItem*>(_poly0));
        connect(this, MouseCoordinate, _poly0, setMouseCoordinate(mousePoint) );
    
    //Same logic for other lines
    }
    

    In MyPoly.cpp

    void MyPoly::setMouseCoOrdinate(QPointF mousePoint)
    {
        this->mouseCoordinate = mousePoint;
    }
    

    But I think I have made a mistake in connect().

    mrjjM 1 Reply Last reply
    0
    • T tushu

      @mrjj
      Yes, I want to create mouseCurrentPosition like global variable. So that everyone ( every MyPoly object ) can access it.

      I have created new Poly in
      void Widget::on_schematicButoon_clicked()
      and I tried like this

      void Widget::on_schematicButoon_clicked()
      {
          QPolygon net0;
          net0 << QPoint(50,180);
          net0 << QPoint(600,180);
          MyPoly* _poly0 = new MyPoly();
          _poly0->DrawPolyline(net0);
          scene->addItem(static_cast<QGraphicsPathItem*>(_poly0));
          connect(this, MouseCoordinate, _poly0, setMouseCoordinate(mousePoint) );
      
      //Same logic for other lines
      }
      

      In MyPoly.cpp

      void MyPoly::setMouseCoOrdinate(QPointF mousePoint)
      {
          this->mouseCoordinate = mousePoint;
      }
      

      But I think I have made a mistake in connect().

      mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #6

      @tushu
      Hi
      first point
      Did remember to add Q_OBJECT to class ?
      like
      class MyPoly : public QGraphicsPathItem
      {
      Q_OBJECT
      public:

      for both classes so you can use signals

      second the connect.
      connect(this, MouseCoordinate, _poly0, setMouseCoordinate(mousePoint) );
      includes mousePoint which is not right.
      also you forgot the classtype in front and the &
      so its more like
      connect(this, &Widget::MouseCoordinate, _poly0, &MyPoly::setMouseCoordinate);

      btw is setMouseCoordinate listed under public slots: in .h ?
      (not sure as code don't show it)

      the & is very important or it will say nasty things to you :)

      T 1 Reply Last reply
      1
      • mrjjM mrjj

        @tushu
        Hi
        first point
        Did remember to add Q_OBJECT to class ?
        like
        class MyPoly : public QGraphicsPathItem
        {
        Q_OBJECT
        public:

        for both classes so you can use signals

        second the connect.
        connect(this, MouseCoordinate, _poly0, setMouseCoordinate(mousePoint) );
        includes mousePoint which is not right.
        also you forgot the classtype in front and the &
        so its more like
        connect(this, &Widget::MouseCoordinate, _poly0, &MyPoly::setMouseCoordinate);

        btw is setMouseCoordinate listed under public slots: in .h ?
        (not sure as code don't show it)

        the & is very important or it will say nasty things to you :)

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

        @mrjj
        Currently I have 3 lines ,

        connect(this,&Widget::MouseCoordinate,_poly,&MyPoly::setMouseCoordinate);
        connect(this,&Widget::MouseCoordinate,_poly0,&MyPoly::setMouseCoordinate);
        connect(this,&Widget::MouseCoordinate,_poly1,&MyPoly::setMouseCoordinate);
        

        In filterEvent

        case QEvent::MouseButtonPress:
           {
               QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
               mousePoint = view->mapToScene(mouseEvent->pos());
               emit MouseCoordinate (mousePoint);
        }
        

        In Widget.h

        class Widget : public QGraphicsView
        {
            Q_OBJECT
        public:
            Widget(QWidget *parent = nullptr);
            ~Widget();
            bool eventFilter(QObject* watched, QEvent* event);
            QPointF mousePoint;
        signals:
            void MouseCoordinate(QPointF);
        

        MyPoly.h

        class MyPoly : public QGraphicsPathItem
        {
            Q_OBJECT
        public:
            explicit MyPoly();
            void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget);
        bool contains(const QPointF &point) const;
            void DrawPolyline(QPolygon polygon);
            QPointF currentCursorPos;
        private:
             QPolygon polygon_;
        public slots:
             void setMouseCoordinate(QPointF);
        };
        

        MyPoly.cpp

        void MyPoly::setMouseCoordinate(QPointF pos)
        {
            this-> currentCursorPos = pos;
        }
        

        Error :
        C:\Qt\5.15.2\mingw81_64\include\QtCore\qobject.h:264: error: no matching function for call to 'QObject::connectImpl(const Object*&, void**, const Object*&, void**, QtPrivate::QSlotObject<void (MyPoly::)(QPointF), QtPrivate::List<QPointF>, void>, Qt::ConnectionType&, const int*&, const QMetaObject*)'

        mrjjM 1 Reply Last reply
        0
        • T tushu

          @mrjj
          Currently I have 3 lines ,

          connect(this,&Widget::MouseCoordinate,_poly,&MyPoly::setMouseCoordinate);
          connect(this,&Widget::MouseCoordinate,_poly0,&MyPoly::setMouseCoordinate);
          connect(this,&Widget::MouseCoordinate,_poly1,&MyPoly::setMouseCoordinate);
          

          In filterEvent

          case QEvent::MouseButtonPress:
             {
                 QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
                 mousePoint = view->mapToScene(mouseEvent->pos());
                 emit MouseCoordinate (mousePoint);
          }
          

          In Widget.h

          class Widget : public QGraphicsView
          {
              Q_OBJECT
          public:
              Widget(QWidget *parent = nullptr);
              ~Widget();
              bool eventFilter(QObject* watched, QEvent* event);
              QPointF mousePoint;
          signals:
              void MouseCoordinate(QPointF);
          

          MyPoly.h

          class MyPoly : public QGraphicsPathItem
          {
              Q_OBJECT
          public:
              explicit MyPoly();
              void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget);
          bool contains(const QPointF &point) const;
              void DrawPolyline(QPolygon polygon);
              QPointF currentCursorPos;
          private:
               QPolygon polygon_;
          public slots:
               void setMouseCoordinate(QPointF);
          };
          

          MyPoly.cpp

          void MyPoly::setMouseCoordinate(QPointF pos)
          {
              this-> currentCursorPos = pos;
          }
          

          Error :
          C:\Qt\5.15.2\mingw81_64\include\QtCore\qobject.h:264: error: no matching function for call to 'QObject::connectImpl(const Object*&, void**, const Object*&, void**, QtPrivate::QSlotObject<void (MyPoly::)(QPointF), QtPrivate::List<QPointF>, void>, Qt::ConnectionType&, const int*&, const QMetaObject*)'

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by mrjj
          #8

          @tushu
          AH sorry my bad.
          I missed you are using QGraphicsPathItem in MyPoly.
          Those are not QObject so default no signals/slots.

          try change it into
          class MyPoly : public QObject, public QGraphicsPathItem {

          (we also inherited a QObject so we can use signal/slots)

          Then completely clean the build folder and try a full rebuild.

          T 2 Replies Last reply
          1
          • mrjjM mrjj

            @tushu
            AH sorry my bad.
            I missed you are using QGraphicsPathItem in MyPoly.
            Those are not QObject so default no signals/slots.

            try change it into
            class MyPoly : public QObject, public QGraphicsPathItem {

            (we also inherited a QObject so we can use signal/slots)

            Then completely clean the build folder and try a full rebuild.

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

            @mrjj
            Thanks. It is working now.

            1 Reply Last reply
            1
            • mrjjM mrjj

              @tushu
              AH sorry my bad.
              I missed you are using QGraphicsPathItem in MyPoly.
              Those are not QObject so default no signals/slots.

              try change it into
              class MyPoly : public QObject, public QGraphicsPathItem {

              (we also inherited a QObject so we can use signal/slots)

              Then completely clean the build folder and try a full rebuild.

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

              @mrjj
              I have a 1 more doubt reagarding another question which is extension of this question.
              Can I post here ?

              mrjjM 1 Reply Last reply
              0
              • T tushu

                @mrjj
                I have a 1 more doubt reagarding another question which is extension of this question.
                Can I post here ?

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by mrjj
                #11

                @tushu
                well if its related , its fine to put here.

                btw one note.
                since you want
                QPointF currentCursorPos;
                to be shared between all instances, you could also make it static.

                That in effect makes it a class variable and its truly shared amount all.

                If this is needed/better, depends on how many Mypoly you are using as each will get a signal and copy the QPopintf
                so if you have like 1000, its more efficient with a shared member but if only a few, don't bother.

                T 5 Replies Last reply
                1
                • mrjjM mrjj

                  @tushu
                  well if its related , its fine to put here.

                  btw one note.
                  since you want
                  QPointF currentCursorPos;
                  to be shared between all instances, you could also make it static.

                  That in effect makes it a class variable and its truly shared amount all.

                  If this is needed/better, depends on how many Mypoly you are using as each will get a signal and copy the QPopintf
                  so if you have like 1000, its more efficient with a shared member but if only a few, don't bother.

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

                  @mrjj
                  s.PNG
                  I am having 3 lines like this with co-ordinates of each points. But their mouse selection is not sharp. If I click on s1, P1 gets selected. Even selection of P1 is also not sharp. If I click around P1 ( not on P1) it gets selected.
                  So I was suggested that override contains() . And write own logic of selecting lines. So I did like this.

                  void MyPoly::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                                        QWidget *widget)
                     {
                         auto copied_option = *option;
                         copied_option.state &= ~QStyle::State_Selected;
                         auto selected = option->state & QStyle::State_Selected;
                         QGraphicsPathItem::paint(painter, &copied_option, widget);
                         if (selected) {
                             painter->save();
                             painter->setPen(QPen(option->palette.windowText(), 0, Qt::SolidLine));
                             if(contains(currentCursorPos)) // mouse click co -ordinates
                                 painter->drawPath(shape());
                             painter->restore();
                         }
                     }
                  
                  bool MyPoly::contains(const QPointF &point) const
                  {
                      for(int i=0;i < polygon_.count() - 1; i++)
                      {
                          QPoint firstPoint = polygon_.at(i);
                          QPoint lastPoint = polygon_.at(i+1);
                          if(firstPoint.x() == lastPoint.x())
                          {
                              qDebug()<<"Inside vertical line ";
                              //It is a vertical line
                              if(firstPoint.x() == point.x() &&
                                      point.y() >= firstPoint.y() && point.y() <= lastPoint.y())
                                  return true;
                          }
                          else
                          {
                              // it is a horizontal line
                              if(point.x() >= firstPoint.x() && point.x() <= lastPoint.x() && point.y() == firstPoint.y() )
                                  return true;
                          }
                      }
                      return false;
                  }
                  

                  Now I am getting mouse click points in paint() method by the method as suggested by you. I am passing those points to contains(). I am able to select S2 line but S1 line is still unselected. If I click on start and end side of S2, it gets selected properly.
                  Can you help me in this ?

                  1 Reply Last reply
                  0
                  • mrjjM mrjj

                    @tushu
                    well if its related , its fine to put here.

                    btw one note.
                    since you want
                    QPointF currentCursorPos;
                    to be shared between all instances, you could also make it static.

                    That in effect makes it a class variable and its truly shared amount all.

                    If this is needed/better, depends on how many Mypoly you are using as each will get a signal and copy the QPopintf
                    so if you have like 1000, its more efficient with a shared member but if only a few, don't bother.

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

                    @mrjj
                    Logic for selecting line :
                    If the line you want to check against is horizontal, then test if the mouse-click's y location is equal to the line's y value (or perhaps within a few pixels of it, to allow for user-slop), and if the mouse-click's x location is between the line's two endpoint x values. Checking against a vertical line is similar.

                    1 Reply Last reply
                    0
                    • mrjjM mrjj

                      @tushu
                      well if its related , its fine to put here.

                      btw one note.
                      since you want
                      QPointF currentCursorPos;
                      to be shared between all instances, you could also make it static.

                      That in effect makes it a class variable and its truly shared amount all.

                      If this is needed/better, depends on how many Mypoly you are using as each will get a signal and copy the QPopintf
                      so if you have like 1000, its more efficient with a shared member but if only a few, don't bother.

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

                      @mrjj
                      One key observation :
                      Addition sequence of lines into scene , matters a lot.
                      If I (first) add P1 -> S1 -> (last) S2 -------- everything works perfectly
                      If I (first) add S2 -> S1 -> (last) P1 -------- S2 Can not be selected
                      If I (first) add S1 -> S2 -> (last) P1 ---------- S1 can not be selected

                      Why ?
                      And how to tackle it ?

                      1 Reply Last reply
                      0
                      • mrjjM mrjj

                        @tushu
                        well if its related , its fine to put here.

                        btw one note.
                        since you want
                        QPointF currentCursorPos;
                        to be shared between all instances, you could also make it static.

                        That in effect makes it a class variable and its truly shared amount all.

                        If this is needed/better, depends on how many Mypoly you are using as each will get a signal and copy the QPopintf
                        so if you have like 1000, its more efficient with a shared member but if only a few, don't bother.

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

                        @mrjj
                        I found this quote :

                        While selecting any of the overlapping lines, the one with bounding rect on top is selected.
                        

                        It is happening with me. If I add P1 line at the end, it will not let me select other lines properly.
                        I found the help : Help
                        I tried their help, but it did not work out with me.
                        They gave eample of single line, but I have QPolygon. ( You can see, in MyPoly.h , you will see

                        private:
                             QPolygon polygon_;
                        

                        My try: ( did not work )

                        QPainterPath MyPoly::shape()
                        {
                                QPainterPath result1; // Here 1st QPainterPath
                                for(int i=0;i < polygon_.count() - 1; i++)
                                {
                                    QPointF firstPoint = polygon_.at(i);
                                    QPointF lastPoint = polygon_.at(i+1);
                        
                                    qDebug()<<"First Point = "<< firstPoint;
                                    qDebug()<<"Second Point = "<< lastPoint;
                        
                                    static const qreal kClickTolerance = 10;
                        
                                    QPointF vec = lastPoint - firstPoint;
                                    vec = vec*(kClickTolerance/qSqrt(QPointF::dotProduct(vec, vec)));
                                    QPointF orthogonal(vec.y(), -vec.x());
                        
                                    QPainterPath result(firstPoint-vec+orthogonal);  // here 1 more QPainterPath 
                                    result.lineTo(firstPoint-vec-orthogonal);
                                    result.lineTo(lastPoint+vec-orthogonal);
                                    result.lineTo(lastPoint+vec+orthogonal);
                                    result.closeSubpath();
                                    result.addPolygon(polygon_);
                                    result1 = result;
                        
                                }
                                return result1;
                        }
                        
                        1 Reply Last reply
                        0
                        • mrjjM mrjj

                          @tushu
                          well if its related , its fine to put here.

                          btw one note.
                          since you want
                          QPointF currentCursorPos;
                          to be shared between all instances, you could also make it static.

                          That in effect makes it a class variable and its truly shared amount all.

                          If this is needed/better, depends on how many Mypoly you are using as each will get a signal and copy the QPopintf
                          so if you have like 1000, its more efficient with a shared member but if only a few, don't bother.

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

                          @mrjj
                          The more I am debugging, I am closing to the real problem in my code.
                          Now I think , I found real problem of my code.
                          For polyline I have used QPolygonF which internally joins start point with end point and make polygon close. And because of that , internally it is becoming closed bounding rect and if I click in that area, only polyline will be selected, no other line passing through that area can be selected.
                          Poly`.PNG

                          If I click on red color area, only P1 will be selected. No S1 or S2 can be selected. So how to tackle this issue ? Or how to avoid polygon to be closed ?
                          Full code and description is in this link. link

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

                            Loop over all edges and find the nearest edge to your mouse click position and then highlight the polygon which includes that edge. If there are overlapped edges, simply choose the first polygon or the one with higher Z value.

                            1 Reply Last reply
                            0
                            • SGaistS Offline
                              SGaistS Offline
                              SGaist
                              Lifetime Qt Champion
                              wrote on last edited by
                              #18

                              Hi,

                              Why not use a QGraphicsPathItem ?

                              It seems to do what you want in terms of painting.

                              Interested in AI ? www.idiap.ch
                              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                              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