QGriphicsView中scene按照鼠标中心和鼠标滚轮操作缩放

Qt 和 c++环境下QGriphicsView怎么屏蔽其本身的滚动条对鼠标滚轮的响应

重写了鼠标滚轮响应事件为缩放View中的GraphicsScene视图,但是view中滚动栏也会响应鼠标滚轮事件导致效果不好,过滤器相关的内容也只找到屏蔽鼠标滚轮,期望效果是让view中scene按照鼠标中心缩放,怎么才能实现这种效果?

你可以通过以下方法实现这种效果:

在QGraphicsView类中重写viewportEvent()函数,并在该函数中过滤掉鼠标滚轮事件。

在QGraphicsView类中重写wheelEvent()函数,实现自己的缩放操作。

例如:

class MyGraphicsView : public QGraphicsView
{
    Q_OBJECT

public:
    MyGraphicsView(QWidget *parent = 0) : QGraphicsView(parent) {}

protected:
    bool viewportEvent(QEvent *event)
    {
        if (event->type() == QEvent::Wheel)
            return true;
        return QGraphicsView::viewportEvent(event);
    }

    void wheelEvent(QWheelEvent *event)
    {
        qreal scaleFactor = 1.15;
        if (event->delta() > 0)
        {
            scale(scaleFactor, scaleFactor);
        }
        else
        {
            scale(1.0 / scaleFactor, 1.0 / scaleFactor);
        }
        event->accept();
    }
};


可以重写QGraphicsView的鼠标滚轮事件,然后再计算出鼠标在View中的位置,根据鼠标位置计算出缩放中心点,最后调用QGraphicsView的scale()函数进行缩放即可。

示例代码如下:

class GraphicsView : public QGraphicsView
{
Q_OBJECT

public:
GraphicsView(QGraphicsScene *scene) : QGraphicsView(scene)
{
}

protected:
virtual void wheelEvent(QWheelEvent *event)
{
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
double scaleFactor = 1.15;
if(event->delta() > 0)
{
// 放大
scale(scaleFactor, scaleFactor);
}
else
{
// 缩小
scale(1.0 / scaleFactor, 1.0 / scaleFactor);
}
}
};

实现过程:

声明一个QGraphicsView的子类,命名为GraphicsView。

在GraphicsView类中,重写wheelEvent()函数。

设置QGraphicsView的变换锚点为AnchorUnderMouse,即按照鼠标位置缩放。

判断鼠标滚轮事件的delta值,如果delta值大于0,说明鼠标向上滚动,调用QGraphicsView的scale()函数放大;如果delta值小于0,说明鼠标向下滚动,调用QGraphicsView的scale()函数缩小。

在main函数中,创建GraphicsView对象,并将QGraphicsScene对象作为参数传入。

这样,当鼠标在QGraphicsView上滚动时,View中的QGraphicsScene会按照鼠标的位置缩放。

    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 隐藏滚动条
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);      // 隐藏滚动条
    setTransformationAnchor(QGraphicsView::AnchorUnderMouse);    // 在鼠标位置进行缩放