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

QCustomPlot and multitouch zoom

Scheduled Pinned Locked Moved General and Desktop
qcustomplottouchpinch
6 Posts 3 Posters 5.8k 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