QCustomPlot and multitouch zoom
-
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?
-
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 ?
-
@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 .
-
You should take a look at the bug report system to see if it's something known
-
@Franckynos @SGaist
Hello,
I have used your function. I got these errors...- _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?
- 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? - 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.
-
@vishnu said:
May i know the use of it?
- yes it's a bool at false in constructor
- 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); }