qwt plot - как сделать масштабирование по курсору мыши

Я использовал QWT для своего проекта. Я использовал Qwtplotmagnifier для масштабирования. Я хочу увеличить масштаб относительно курсора мыши. Можешь мне помочь?


person Süleyman Kabadayı    schedule 29.04.2018    source источник
comment
Пожалуйста, будьте более точны. Что вы имеете в виду под курсором мыши? Вы действительно имеете в виду относительно движения курсора мыши?   -  person sirop    schedule 30.04.2018
comment
масштабирование курсора мыши с помощью колесика мыши, поэтому центр масштабирования = курсор мыши   -  person Süleyman Kabadayı    schedule 30.04.2018
comment
О типе масштабирования см. qwt.sourceforge.net/class_qwt_plot_zoomer.html и его родительские классы, особенно qwt.sourceforge.net/class_qwt_event_pattern.html .   -  person sirop    schedule 30.04.2018
comment
спасибо, я проанализировал, но я использовал лупу для увеличения.   -  person Süleyman Kabadayı    schedule 03.05.2018


Ответы (2)


У меня была такая же проблема, и я не мог найти ответа, поэтому вот мой. На основе этого сообщения: Расчет смещение вида для увеличения в позиции курсора мыши

Чтобы реализовать масштабирование в стиле 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();
}

Это отлично работает для меня.

person Victor    schedule 14.09.2020

На основании этого сообщения на форуме:

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);
    }
}
person lena    schedule 18.02.2019