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