I am trying to implement zooming in/out feature on Qt and I've tried almost all methods on this post, but none of them works.
It can zoom in/out with right ratio, but y position jumps randomly after wheeling (x position seems correct)
Reproduce on Qt creator:
- Create Qt Widgets Application
- On "design" page, drag a Graphics View from "Display Widgets" (Default objectName is "graphicsView")
- Declare 1 variable, 3 functions and 1 private slots on
MainWindow.h
public:
QGraphicsView* m_pDrawingArea;
void setupView();
void setupDefaultDrawing();
void eventDrawingArea_Wheel(QWheelEvent* event);
private slots:
bool eventFilter(QObject* object, QEvent* event) override;
- set up variable and function calls in contructor
ui->setupUi(this);
m_pDrawingArea = findChild<QGraphicsView*>("graphicsView");
setupView();
setupDefaultDrawing();
- fill setupView() and setupDefaultDrawing()
void MainWindow::setupView(){
QGraphicsScene* pScene = new QGraphicsScene(this);
m_pDrawingArea->setScene(pScene);
//reverse y axis
m_pDrawingArea->scale(1, -1);
//mouse event
m_pDrawingArea->setMouseTracking(true);
m_pDrawingArea->viewport()->installEventFilter(this);
//set viewportupdatemode to fullview
m_pDrawingArea->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
}
void MainWindow::setupDefaultDrawing(){
//use two axis to extend scence
int width = m_pDrawingArea->width()*100;
int height = m_pDrawingArea->height()*100;
QGraphicsLineItem* pXAxis = new QGraphicsLineItem(-width / 2, 0, width / 2, 0);
QGraphicsLineItem* pYAxis = new QGraphicsLineItem(0, -height / 2, 0, height / 2);
m_pDrawingArea->scene()->addItem(pXAxis);
m_pDrawingArea->scene()->addItem(pYAxis);
//a point for test
QGraphicsEllipseItem* pPoint = new QGraphicsEllipseItem(100, 100, 1, 1);
pPoint->setPen(QPen(Qt::black, 1, Qt::SolidLine));
pPoint->setBrush(QBrush(Qt::black));
m_pDrawingArea->scene()->addItem(pPoint);
}
- create mouse wheel event
bool MainWindow::eventFilter(QObject* object, QEvent* event){
if (object == m_pDrawingArea->viewport() && event->type() == QEvent::Wheel){
eventDrawingArea_Wheel(static_cast<QWheelEvent*>(event));
}
return QMainWindow::eventFilter(object, event);
}
void MainWindow::eventDrawingArea_Wheel(QWheelEvent* wheelEvent){
QPointF oldPos = m_pDrawingArea->mapToScene(wheelEvent->pos());
if (wheelEvent->modifiers() & Qt::ControlModifier) {
// zoom
QGraphicsView::ViewportAnchor anchor = m_pDrawingArea->transformationAnchor();
m_pDrawingArea->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
int angle = wheelEvent->angleDelta().y();
qreal scaleFactor = (angle > 0) ? 1.25 : 1 / 1.25;
m_pDrawingArea->scale(scaleFactor, scaleFactor);
QPointF newPos = m_pDrawingArea->mapToScene(wheelEvent->pos());
m_pDrawingArea->translate(newPos.x() - oldPos.x(), newPos.y() - oldPos.y());
m_pDrawingArea->setTransformationAnchor(anchor);
} else {
// QGraphicsView::wheelEvent(wheelEvent);
}
}