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. QCustomPlot and multitouch zoom
QtWS25 Last Chance

QCustomPlot and multitouch zoom

Scheduled Pinned Locked Moved General and Desktop
qcustomplottouchpinch
6 Posts 3 Posters 5.7k Views
  • 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.
  • FranckynosF Offline
    FranckynosF Offline
    Franckynos
    wrote on last edited by
    #1

    Hi everybody.

    I use QCustomPlot library and I would like use my application on tablet.
    But I have some trouble to interact with 2 touchs for zoom.

    I try to write this:

    bool CustomPlot::event(QEvent* event)
    {
    if(event->type() == QEvent::TouchBegin ||
    event->type() == QEvent::TouchUpdate ||
    event->type() == QEvent::TouchEnd ){
    QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
    QListQTouchEvent::TouchPoint touchPoints = touchEvent->touchPoints();

        if(touchPoints.count() == 1 && touchEvent->touchPointStates().testFlag(Qt::TouchPointReleased))
            _release2touch = false;
    
        if (touchPoints.count() == 1 && !_release2touch)
        {
            switch (event->type()) {
            case QEvent::TouchBegin:
            {
                QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
                QTouchEvent::TouchPoint touchPoints = touchEvent->touchPoints().first();
                QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonPress,
                                                 touchPoints.pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
    
                emit mousePressEvent(e);
                return true;
    
            }break;
    
            case QEvent::TouchUpdate:
            {
                QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
                QTouchEvent::TouchPoint touchPoints = touchEvent->touchPoints().first();
                QMouseEvent *e = new QMouseEvent(QEvent::MouseMove,
                                                 touchPoints.pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
    
                emit mouseMoveEvent(e);
                return true;
    
            }break;
    
            case QEvent::TouchEnd:{
                QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
                QTouchEvent::TouchPoint touchPoints = touchEvent->touchPoints().first();
                QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonRelease,
                                                 touchPoints.pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
    
                emit mouseReleaseEvent(e);
                return true;
    
            }break;
    
            default:
                return false;
                break;
            }
        }else if (touchPoints.count() == 2) {
            _release2touch = true;
            // determine scale factor
            const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();
            const QTouchEvent::TouchPoint &touchPoint1 = touchPoints.last();
            double currentScaleFactor =
                    QLineF(touchPoint0.pos(), touchPoint1.pos()).length() /
                    QLineF(touchPoint0.lastPos(), touchPoint1.lastPos()).length();
    
            QPointF centreZoom = QPointF((touchPoint0.pos().x()+ touchPoint1.pos().x())/2 ,
                                         (touchPoint0.pos().y()+ touchPoint1.pos().y())/2);
            QPointF lastCenterZoom = QPointF((touchPoint0.lastPos().x()+ touchPoint1.lastPos().x())/2 ,
                                             (touchPoint0.lastPos().y()+ touchPoint1.lastPos().y())/2);
    
            if (touchEvent->touchPointStates().testFlag(Qt::TouchPointReleased))
                currentScaleFactor = 1;
    
            if(currentScaleFactor<1)
                currentScaleFactor = currentScaleFactor + (1-currentScaleFactor)/8;
            else
                currentScaleFactor = currentScaleFactor+(currentScaleFactor-1)/8;
    
            currentScaleFactor =1/currentScaleFactor;
    
            double diffX = this->xAxis->pixelToCoord(lastCenterZoom.x())
                    - this->xAxis->pixelToCoord(centreZoom.x());
    
            double diffY = this->yAxis->pixelToCoord(lastCenterZoom.y())
                    - this->yAxis->pixelToCoord(centreZoom.y());
    
            if(!touchEvent->touchPointStates().testFlag(Qt::TouchPointReleased)){
                this->xAxis->moveRange(diffX);
                this->yAxis->moveRange(diffY);
                this->xAxis->scaleRange(currentScaleFactor,this->xAxis->pixelToCoord(centreZoom.x()));
                this->yAxis->scaleRange(currentScaleFactor,this->yAxis->pixelToCoord(centreZoom.y()));
                this->replot();
            }
            return true;
        }
    }else{
        return QWidget::event(event);
    }
    return false;  // a ajouter ?
    

    }

    When I was in 32 bits on Qt 5.2 this code works fine...
    I upgrade my code to 64 bits with Qt 5.4, and I have some trouble, the interaction is not running fluid.

    Someone can hlep me ? I'm not sure with my methode?

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

      Hi,

      The change of architecture should not have any influence on the matter but you might be hitting a regression. What difference are you seeing ?

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

      FranckynosF 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        The change of architecture should not have any influence on the matter but you might be hitting a regression. What difference are you seeing ?

        FranckynosF Offline
        FranckynosF Offline
        Franckynos
        wrote on last edited by
        #3

        @SGaist Hi, I think is come from Windows 8.
        My tablet run under windows 8.1 and simulate the touch point by mouse action. I have make some modification like that :

        if(_touchDevice)
        {
        if(event->type() == QEvent::MouseButtonDblClick ||
        event->type() == QEvent::MouseButtonPress ||
        event->type() == QEvent::MouseButtonRelease ||
        event->type() == QEvent::MouseMove ||
        event->type() == QEvent::MouseTrackingChange)
        {
        event->ignore();
        return true;
        }
        }

        And with this, it work very well and it's fluid. But now it doesn't work on PC ... Because I block mouse even .

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

          You should take a look at the bug report system to see if it's something known

          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
          • FranckynosF Franckynos

            Hi everybody.

            I use QCustomPlot library and I would like use my application on tablet.
            But I have some trouble to interact with 2 touchs for zoom.

            I try to write this:

            bool CustomPlot::event(QEvent* event)
            {
            if(event->type() == QEvent::TouchBegin ||
            event->type() == QEvent::TouchUpdate ||
            event->type() == QEvent::TouchEnd ){
            QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
            QListQTouchEvent::TouchPoint touchPoints = touchEvent->touchPoints();

                if(touchPoints.count() == 1 && touchEvent->touchPointStates().testFlag(Qt::TouchPointReleased))
                    _release2touch = false;
            
                if (touchPoints.count() == 1 && !_release2touch)
                {
                    switch (event->type()) {
                    case QEvent::TouchBegin:
                    {
                        QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
                        QTouchEvent::TouchPoint touchPoints = touchEvent->touchPoints().first();
                        QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonPress,
                                                         touchPoints.pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
            
                        emit mousePressEvent(e);
                        return true;
            
                    }break;
            
                    case QEvent::TouchUpdate:
                    {
                        QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
                        QTouchEvent::TouchPoint touchPoints = touchEvent->touchPoints().first();
                        QMouseEvent *e = new QMouseEvent(QEvent::MouseMove,
                                                         touchPoints.pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
            
                        emit mouseMoveEvent(e);
                        return true;
            
                    }break;
            
                    case QEvent::TouchEnd:{
                        QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
                        QTouchEvent::TouchPoint touchPoints = touchEvent->touchPoints().first();
                        QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonRelease,
                                                         touchPoints.pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
            
                        emit mouseReleaseEvent(e);
                        return true;
            
                    }break;
            
                    default:
                        return false;
                        break;
                    }
                }else if (touchPoints.count() == 2) {
                    _release2touch = true;
                    // determine scale factor
                    const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();
                    const QTouchEvent::TouchPoint &touchPoint1 = touchPoints.last();
                    double currentScaleFactor =
                            QLineF(touchPoint0.pos(), touchPoint1.pos()).length() /
                            QLineF(touchPoint0.lastPos(), touchPoint1.lastPos()).length();
            
                    QPointF centreZoom = QPointF((touchPoint0.pos().x()+ touchPoint1.pos().x())/2 ,
                                                 (touchPoint0.pos().y()+ touchPoint1.pos().y())/2);
                    QPointF lastCenterZoom = QPointF((touchPoint0.lastPos().x()+ touchPoint1.lastPos().x())/2 ,
                                                     (touchPoint0.lastPos().y()+ touchPoint1.lastPos().y())/2);
            
                    if (touchEvent->touchPointStates().testFlag(Qt::TouchPointReleased))
                        currentScaleFactor = 1;
            
                    if(currentScaleFactor<1)
                        currentScaleFactor = currentScaleFactor + (1-currentScaleFactor)/8;
                    else
                        currentScaleFactor = currentScaleFactor+(currentScaleFactor-1)/8;
            
                    currentScaleFactor =1/currentScaleFactor;
            
                    double diffX = this->xAxis->pixelToCoord(lastCenterZoom.x())
                            - this->xAxis->pixelToCoord(centreZoom.x());
            
                    double diffY = this->yAxis->pixelToCoord(lastCenterZoom.y())
                            - this->yAxis->pixelToCoord(centreZoom.y());
            
                    if(!touchEvent->touchPointStates().testFlag(Qt::TouchPointReleased)){
                        this->xAxis->moveRange(diffX);
                        this->yAxis->moveRange(diffY);
                        this->xAxis->scaleRange(currentScaleFactor,this->xAxis->pixelToCoord(centreZoom.x()));
                        this->yAxis->scaleRange(currentScaleFactor,this->yAxis->pixelToCoord(centreZoom.y()));
                        this->replot();
                    }
                    return true;
                }
            }else{
                return QWidget::event(event);
            }
            return false;  // a ajouter ?
            

            }

            When I was in 32 bits on Qt 5.2 this code works fine...
            I upgrade my code to 64 bits with Qt 5.4, and I have some trouble, the interaction is not running fluid.

            Someone can hlep me ? I'm not sure with my methode?

            vishnuV Offline
            vishnuV Offline
            vishnu
            wrote on last edited by vishnu
            #5

            @Franckynos @SGaist
            Hello,
            I have used your function. I got these errors...

            1. _release2touch was not declared in this scope...I hope it is of type bool ,so i have declared a member variable bool release2touch. May i know the use of it?
            2. error: cannot call member function 'virtual bool QWidget::event(QEvent*)' without object
              return QWidget::event(event); ....At the return statement it is there...What should i do to remove this error?
            3. How should i make use of this function ? I mean when does this function is called ?How can I call this function esp from QML if you don't know qml atleast give me an example in C+++.thanks a lot.
            1 Reply Last reply
            0
            • FranckynosF Offline
              FranckynosF Offline
              Franckynos
              wrote on last edited by
              #6

              @vishnu said:

              May i know the use of it?

              1. yes it's a bool at false in constructor
              2. you have forget event in prototype :
                'virtual bool QWidget::event(QEvent*)' without object in => 'virtual bool QWidget::event(QEvent* !!! event !!! )' without object
              CustomPlot::CustomPlot(QWidget *parent)
                  :QCustomPlot(parent)
              {
                  setAttribute(Qt::WA_AcceptTouchEvents);
                  _release2touch = false;
                  _touchDevice = false;
              }
              
              bool CustomPlot::event(QEvent* event)
              {
                  if(_touchDevice)
                  {
                      if(event->type() == QEvent::MouseButtonDblClick ||
                              event->type() == QEvent::MouseButtonPress ||
                              event->type() == QEvent::MouseButtonRelease ||
                              event->type() == QEvent::MouseMove ||
                              event->type() == QEvent::MouseTrackingChange)
                      {
                          event->ignore();
                          return true;
                      }
              
                      if(event->type() == QEvent::Wheel)
                          _touchDevice = false;
                  }
              
                  if(event->type() == QEvent::TouchBegin ||
                          event->type() == QEvent::TouchUpdate ||
                          event->type() == QEvent::TouchEnd ){
              
                      if(!_touchDevice)
                          _touchDevice = true;
              
                      QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
                      QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
              
                      if(touchPoints.count() == 1 && touchEvent->touchPointStates().testFlag(Qt::TouchPointReleased))
                          _release2touch = false;
              
                      if (touchPoints.count() == 1 && !_release2touch)
                      {
                          switch (event->type()) {
                          case QEvent::TouchBegin:
                          {
                              QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
                              QTouchEvent::TouchPoint touchPoints = touchEvent->touchPoints().first();
                              QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonPress,
                                                               touchPoints.pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
              
                              mousePressEvent(e); //==> meilleure methode
                          }break;
              
                          case QEvent::TouchUpdate:
                          {
                              QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
                              QTouchEvent::TouchPoint touchPoints = touchEvent->touchPoints().first();
                              QMouseEvent *e = new QMouseEvent(QEvent::MouseMove,
                                                               touchPoints.pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
              
                              mouseMoveEvent(e);
                          }break;
              
                          case QEvent::TouchEnd:{
                              QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
                              QTouchEvent::TouchPoint touchPoints = touchEvent->touchPoints().first();
                              QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonRelease,
                                                               touchPoints.pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
              
                              mouseReleaseEvent(e);
                          }break;
              
                          default:
                              break;
                          }
                      }else if (touchPoints.count() == 2) {
                          _release2touch = true;
                          // determine scale factor
                          const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();
                          const QTouchEvent::TouchPoint &touchPoint1 = touchPoints.last();//   touchPoints.last();
              
                          double currentScaleFactor =
                                  QLineF(touchPoint0.pos(), touchPoint1.pos()).length() /
                                  QLineF(touchPoint0.lastPos(), touchPoint1.lastPos()).length();
              
                          QPointF centreZoom = QPointF((touchPoint0.pos().x()+ touchPoint1.pos().x())/2 ,
                                                       (touchPoint0.pos().y()+ touchPoint1.pos().y())/2);
                          QPointF lastCenterZoom = QPointF((touchPoint0.lastPos().x()+ touchPoint1.lastPos().x())/2 ,
                                                           (touchPoint0.lastPos().y()+ touchPoint1.lastPos().y())/2);
              
                          if (touchEvent->touchPointStates().testFlag(Qt::TouchPointReleased))
                              currentScaleFactor = 1;
              
              
                          if(currentScaleFactor<1)
                              currentScaleFactor = currentScaleFactor + (1-currentScaleFactor)/8;
                          else
                              currentScaleFactor = currentScaleFactor+ (currentScaleFactor-1)/8;
              
                          currentScaleFactor =1/currentScaleFactor;
              
                          double diffX = this->xAxis->pixelToCoord(lastCenterZoom.x())
                                  - this->xAxis->pixelToCoord(centreZoom.x());
              
                          double diffY = this->yAxis->pixelToCoord(lastCenterZoom.y())
                                  - this->yAxis->pixelToCoord(centreZoom.y());
              
                          if(!touchEvent->touchPointStates().testFlag(Qt::TouchPointReleased)){
                              this->xAxis->moveRange(diffX);
                              this->yAxis->moveRange(diffY);
                              this->xAxis->scaleRange(currentScaleFactor,this->xAxis->pixelToCoord(centreZoom.x()));
                              this->yAxis->scaleRange(currentScaleFactor,this->yAxis->pixelToCoord(centreZoom.y()));
                              this->replot();
                          }
                      }
                      return true;
                  }
                  return QWidget::event(event);
              }
              
              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