QWheelEvent not working when using N.2 QGraphicsView in the same UI

时光毁灭记忆、已成空白 提交于 2019-12-09 04:21:28

You must learn about the Single responsibility principle, where it indicates that each class has its own responsibility, and in this case it would avoid having a lot of messiness. The responsibility of the zoom is of the QGraphicsView, it is not the one of the MainWindow.

To do this, a new class is created that inherits from QGraphicsView and we implement the zoom functionality:

graphicsview.h

#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H

#include <QGraphicsView>

class GraphicsView : public QGraphicsView
{
public:
    GraphicsView(QWidget *parent=nullptr);
    void setModifiers(const Qt::KeyboardModifiers &modifiers);
protected:
    void wheelEvent(QWheelEvent *event) override;
private:
    void applyZoom(double factor, const QPoint &fixedViewPos);
    Qt::KeyboardModifiers m_modifiers;
    const double base = 1.0015;
};

#endif // GRAPHICSVIEW_H

graphicsview.cpp

#include "graphicsview.h"

#include <QWheelEvent>
#include <QtMath>

GraphicsView::GraphicsView(QWidget *parent):
    QGraphicsView(parent)
{}

void GraphicsView::setModifiers(const Qt::KeyboardModifiers &modifiers)
{
    m_modifiers = modifiers;
}

void GraphicsView::wheelEvent(QWheelEvent *event)
{
    if(event->modifiers() == m_modifiers){
        double angle = event->orientation() == Qt::Vertical ? event->angleDelta().y(): event->angleDelta().x();
        double factor = qPow(base, angle);
        applyZoom(factor, event->pos());
    }
}

void GraphicsView::applyZoom(double factor, const QPoint & fixedViewPos)
{
    QPointF fixedScenePos = mapToScene(fixedViewPos);
    centerOn(fixedScenePos);
    scale(factor, factor);
    QPointF delta = mapToScene(fixedViewPos) - mapToScene(viewport()->rect().center());
    centerOn(fixedScenePos - delta);
}

Then using the widget promotion offered by Qt Designer is inserted into the GUI. And then set the values:

ui->rightView->setModifiers(Qt::AltModifier);
ui->leftView->setModifiers(Qt::ControlModifier);

The complete example can be found here.


On the other hand many of the code examples that are shown in SO are only to show the functionality and not necessarily be used for the implementation of the projects because having little space here is compressed sometimes losing readability. For example, I have based on the idea of the answer that you point out but I have divided it correctly to have a clean code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!