Eventos de ratón en el QGraphicsView

miércoles, julio 16, 2008

El QGraphicsView es una clase de Qt4 que proporciona un widget para mostrar una escena QGraphicsScene. La escena es una superficie que nos permite manejar un montón de elementos 2D, sin embargo ninguno de estos controles trae habilitado por defecto la captura de eventos de ratón.

Para interceptar (y manejar) estos eventos debemos hacer una subclase, bien sea, de QGraphicsScene o de QGraphicsView y redefinir el método mousePressEvent. Pero como QGraphicsView contiene a la escena (digamos que es el widget padre) entonces lo tomaremos como base para esta explicación.

Vamos a definir una subclase válida de un QGraphicsView llamada GraphicsView y que tenga una señal llamada mousePressed con dos argumentos enteros:
#include <QGraphicsView>
#include <QObject>

class GraphicsView : public QGraphicsView{
Q_OBJECT
public:
GraphicsView(QWidget *parent = 0);
void mousePressEvent(QMouseEvent *event);
signals:
void mousePressed(int x, int y);
};

El método mousePressEvent se llamará cada vez que el usuario haga clic en un botón del ratón encima del GraphicsView. Para implementar otros eventos de ratón podemos redefinir (de la misma manera) las funciones mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent o wheelEvent.

La reimplementación de la clase quedaría de la siguiente forma:
GraphicsView::GraphicsView(QWidget *parent) : QGraphicsView(parent) {
/* Aquí se coloca todo el código necesario para la creación e
inicialización del widget */
}

/* Redefinición del método mousePressEvent para tomar las coordenadas x e y del
ratón y almacenarlas en las variables enteras xRaton y yRaton respectivamente */

void GraphicsView::mousePressEvent(QMouseEvent *event){
int xRaton = event->pos().x();
int yRaton = event->pos().y();

//emitir la señal mousePressed
emit mousePressed(xRaton, yRaton);
}

Para utilizar esta subclase solo debemos instanciarla y conectar la señal mousePressed a un slot de nuestra preferencia, por ejemplo:
GraphicsView *visor; //Instanciamos un puntero a un elemento GraphicsView
visor = new GraphicsView(this);

connect(visor, SIGNAL(mousePressed(int, int)), this, SLOT(slot_prara_manejar_raton(int, int)));

Con esto tendremos un QGraphicsView que soporta eventos de ratón :D