I used QWT for my project. I used Qwtplotmagnifier for zoom. I want to zoom in relative to the mouse cursor. Can you Help me?
Asked
Active
Viewed 1,618 times
0
-
Please be more precise. What do you mean with "relative to the mouse cursor"? Do you actually mean "relative to mouse cursor movement"? – sirop Apr 30 '18 at 06:47
-
zoom mouse cursor around with mouse wheel, so zoom center = mouse cursor – Süleyman Kabadayı Apr 30 '18 at 10:15
-
For the type of zooming see http://qwt.sourceforge.net/class_qwt_plot_zoomer.html and its parent classes, especially, http://qwt.sourceforge.net/class_qwt_event_pattern.html . – sirop Apr 30 '18 at 11:48
-
thank you ,i analyzed but ı used plotmagnifier for zooming . – Süleyman Kabadayı May 03 '18 at 10:31
2 Answers
1
I had the same problem and I could not find any answer, so here is mine. Based on this post : Calculating view offset for zooming in at the position of the mouse cursor
In order to implement a GoogleMap-style zoom, you have to inherit from QwtPlotMagnifier and reimplement widgetWheelEvent
in order to store the cursor position when a scroll happens, and rescale
function, to change the behavior of the zoom.
//widgetWheelEvent method
void CenterMouseMagnifier::widgetWheelEvent(QWheelEvent *wheelEvent)
{
this->cursorPos = wheelEvent->pos();
QwtPlotMagnifier::widgetWheelEvent(wheelEvent);
}
For the rescale
method, I used the source code and modified it. You need to use the QwtScaleMap object of the canvas to transform the mouse cursor coordinates into axis coordinates of your plot. And finally, you just need to apply the formula given in the other post.
//rescale method
void CenterMouseMagnifier::rescale(double factor)
{
QwtPlot* plt = plot();
if ( plt == nullptr )
return;
factor = qAbs( factor );
if ( factor == 1.0 || factor == 0.0 )
return;
bool doReplot = false;
const bool autoReplot = plt->autoReplot();
plt->setAutoReplot( false );
for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
{
if ( isAxisEnabled( axisId ) )
{
const QwtScaleMap scaleMap = plt->canvasMap( axisId );
double v1 = scaleMap.s1(); //v1 is the bottom value of the axis scale
double v2 = scaleMap.s2(); //v2 is the top value of the axis scale
if ( scaleMap.transformation() )
{
// the coordinate system of the paint device is always linear
v1 = scaleMap.transform( v1 ); // scaleMap.p1()
v2 = scaleMap.transform( v2 ); // scaleMap.p2()
}
double c=0; //represent the position of the cursor in the axis coordinates
if (axisId == QwtPlot::xBottom) //we only work with these two axis
c = scaleMap.invTransform(cursorPos.x());
if (axisId == QwtPlot::yLeft)
c = scaleMap.invTransform(cursorPos.y());
const double center = 0.5 * ( v1 + v2 );
const double width_2 = 0.5 * ( v2 - v1 ) * factor;
const double newCenter = c - factor * (c - center);
v1 = newCenter - width_2;
v2 = newCenter + width_2;
if ( scaleMap.transformation() )
{
v1 = scaleMap.invTransform( v1 );
v2 = scaleMap.invTransform( v2 );
}
plt->setAxisScale( axisId, v1, v2 );
doReplot = true;
}
}
plt->setAutoReplot( autoReplot );
if ( doReplot )
plt->replot();
}
This works fine for me.

Victor
- 11
- 1
0
Based on this forum post:
bool ParentWidget::eventFilter(QObject *o, QEvent *e)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(e);
if (mouseEvent->type()==QMouseEvent::MouseButtonPress && ((mouseEvent->buttons() & Qt::LeftButton)==Qt::LeftButton)) //do zoom on a mouse click
{
QRectF widgetRect(mouseEvent->pos().x() - 50, mouseEvent->pos().y() - 50, 100, 100); //build a rectangle around mouse cursor position
const QwtScaleMap xMap = plot->canvasMap(zoom->xAxis());
const QwtScaleMap yMap = plot->canvasMap(zoom->yAxis());
QRectF scaleRect = QRectF(
QPointF(xMap.invTransform(widgetRect.x()), yMap.invTransform(widgetRect.y())),
QPointF(xMap.invTransform(widgetRect.right()), yMap.invTransform(widgetRect.bottom())) ); //translate mouse rectangle to zoom rectangle
zoom->zoom(scaleRect);
}
}

lena
- 1,181
- 12
- 36