Tag Archives: QGraphicsView

QGraphicsView: zoom

1. Idea general
La idea es que la rueda del ratón pueda utilizarse para ampliar y reducir la parte de la escena sobre la que está el ratón. El encargado del zoom es el QGraphicsView pero los eventos del ratón los estoy capturando con un QGraphicsScene modificado. Para que funcione hay que decirle al QGraphicsScene quien es su view. Para eso añado una función y la correspondiente variable:

public:
    void setView(QGraphicsView * v);

private:
    QGraphicsView * view;

La escena incluye una variable para controlar el factor de zoom:

qreal scaleValue;

En el constructor le asigno un valor 100 y luego se va modificando con la rueda del ratón.

Para mantener la vista encima del ratón hay que modificar la propiedad transformationAnchor del QGraphicsView:

ui->graphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
}

Esto falla cuando el tamaño de la escena es inferior al tamaño del QGraphicsView, pero en general funciona.

2. Captura del movimiento de la rueda del ratón.
La función delta() dice el sentido en que se ha girado la rueda: positivo hacia adelante, negativo hacia detrás.

bool MyGraphicsScene::eventFilter(QObject *watched, QEvent *event) {
    if (watched == this && (event->type()==QEvent::GraphicsSceneWheel)) {
        QGraphicsSceneWheelEvent * ew =  static_cast<QGraphicsSceneWheelEvent *>(event);
        qDebug() << "rueda" << ew->delta();
        qDebug() << "---";
        if (ew->delta() >0) {
            zoomIn();
        } else {
            zoomOut();
        }
        event->accept();
    }
}

<br />
</p><strong>3. Ampliación y reducción.</strong>
El control del zoom lo hago a través de la variable <em>scaleValue</em>. Los limites 7400 como máxima ampliación y 2 como mínima parece que funcionan.
Para decirle al <em>QGraphicsView</em> que <strong>doble</strong> la vista de la escena, tanto vertical como horizontal:

        view->scale(2,2);
        view->repaint();

Para reducir la vista a la mitad, lo mismo en vertical como horizontal:

        view->scale(0.5,0.5);
        view->repaint();

4. Las funciones del zoom.

void MyGraphicsScene::zoomIn(){
    if (scaleValue < 7400) {
        scaleValue *=2;
        view->scale(2,2);
        view->repaint();
    }
    qDebug() << "zoomIn:" << scaleValue;
}

void MyGraphicsScene::zoomOut() {
    if (scaleValue > 2) {
        scaleValue /=2;
        qDebug() << "scale:" << scaleValue;
        view->scale(0.5,0.5);
        view->repaint();
    }
   qDebug() << "zoomout" << scaleValue;
}

5. Más
Los eventos del QGraphicsScene

Dibujo en Qt. Parte I. El comienzo.

1. Añadir el QGraphicsView a la ventana principal desde el editor gráfico. Los dibujos se hacen sobre un QGraphicsScene que hay que añadir en el mainwindow.h

El mainwindow.h se queda así:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QGraphicsScene>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    Ui::MainWindow *ui;
    QGraphicsScene scene;
};

#endif // MAINWINDOW_H

2. Preparar el QGraphicsScene.
2.1. Lo primero darle tamaño al QGraphcsScene y tener una pluma con la que dibujar. En el constructor del mainWindow poner lo siguiente:

//includes
#include "QGraphicsView"
#include "QRectF"

QRectF rect(0,0,640,480); //Escena de 640x480
QPen  pen; //Pluma por defecto: Negro y 1px de ancho.

scene.setSceneRect(rect);

2.2. Dibujar algo. Un marco para la escena, una retícula y un saludo.

    scene.addText("hola mundo!");

    scene.addLine(0,0,640,0,pen);
    scene.addLine(640,0,640,480,pen);
    scene.addLine(0,480,640,480,pen);
    scene.addLine(0,0,0,480,pen);

    for (int x = 0; x < 640; x+=20) {
        scene.addLine(x,0,x,480,pen);
    }

    for (int y = 0; y < 480; y+=20) {
        scene.addLine(0,y,640,y,pen);
    }
}

3. Mostrar la escena.

    ui->graphicsView->setScene(&scene);
    ui->graphicsView->show();

4. Conclusión.
El constructor se queda así:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QRectF rect(0,0,640,480);
    QPen  pen;

    scene.setSceneRect(rect);
    scene.addText("hola mundo!");

    scene.addLine(0,0,640,0,pen);
    scene.addLine(640,0,640,480,pen);
    scene.addLine(0,480,640,480,pen);
    scene.addLine(0,0,0,480,pen);

    for (int x = 0; x < 640; x+=20) {
        scene.addLine(x,0,x,480,pen);
    }

    for (int y = 0; y < 480; y+=20) {
        scene.addLine(0,y,640,y,pen);
    }


    ui->graphicsView->setScene(&scene);
    ui->graphicsView->show();
}

Continuá..