qwt plot - как сделать масштабирование в соответствии с курсором мыши
Я использовал QWT для своего проекта. Я использовал Qwtplotmagnifier для увеличения. Я хочу увеличить масштаб относительно курсора мыши. Вы не могли бы мне помочь?
0 ответов
У меня была такая же проблема, и я не мог найти ответа, поэтому вот мой. На основе этого сообщения: Расчет смещения вида для увеличения в позиции курсора мыши
Чтобы реализовать масштабирование в стиле GoogleMap, вы должны унаследовать от QwtPlotMagnifier и переопределить
widgetWheelEvent
чтобы сохранить позицию курсора при прокрутке, и
rescale
функция, чтобы изменить поведение масштабирования.
//widgetWheelEvent method
void CenterMouseMagnifier::widgetWheelEvent(QWheelEvent *wheelEvent)
{
this->cursorPos = wheelEvent->pos();
QwtPlotMagnifier::widgetWheelEvent(wheelEvent);
}
Для
rescale
метод, я использовал исходный код и модифицировал его. Вам нужно использовать объект QwtScaleMap холста, чтобы преобразовать координаты курсора мыши в координаты оси вашего графика. И наконец, вам просто нужно применить формулу, приведенную в другом посте.
//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();
}
У меня это отлично работает.
Основываясь на этом сообщении на форуме:
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);
}
}