qwt plot - 如何根据鼠标光标进行缩放

Posted

技术标签:

【中文标题】qwt plot - 如何根据鼠标光标进行缩放【英文标题】:qwt plot - how to make zoom according to mouse cursor 【发布时间】:2018-04-29 15:43:39 【问题描述】:

我在我的项目中使用了 QWT。我使用 Qwtplotmagnifier 进行缩放。 我想相对于鼠标光标放大。你能帮帮我吗?

【问题讨论】:

请更准确。 “相对于鼠标光标”是什么意思?您的意思是“相对于鼠标光标移动”吗? 用鼠标滚轮缩放鼠标光标,所以缩放中心=鼠标光标 有关缩放类型,请参见qwt.sourceforge.net/class_qwt_plot_zoomer.html 及其父类,尤其是qwt.sourceforge.net/class_qwt_event_pattern.html。 谢谢你,我分析了,但我用 plotmagnifier 进行缩放。 【参考方案1】:

我有同样的问题,我找不到任何答案,所以这是我的。 基于这篇文章:Calculating view offset for zooming in at the position of the mouse cursor

为了实现 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();

这对我来说很好。

【讨论】:

【参考方案2】:

基于此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);
    

【讨论】:

以上是关于qwt plot - 如何根据鼠标光标进行缩放的主要内容,如果未能解决你的问题,请参考以下文章

使用 ctrl + 鼠标滚轮进行缩放

缩放画布到鼠标光标

计算在鼠标光标位置放大的视图偏移

【缩放】实现svg以鼠标为焦点缩放

threeJS 导入模型(不确定尺寸)后如何确定相机位置及物体缩放比例

如何在 OpenGL/Glut 中更改鼠标光标的位置?