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 - 如何根据鼠标光标进行缩放的主要内容,如果未能解决你的问题,请参考以下文章