2011-01-20 17 views
18

Actualmente puedo cargar mi imagen en una escena de grahpics y luego de nuevo en un QGraphicsViewer.cómo desplazar imágenes en QGraphicsView

Soy capaz de implementar una función de zoom al marcar un QEvent :: Wheel y luego llamar a la función scale() de graphicsViews.

Sin embargo, parece que no puedo entender cómo funciona la función pan. Básicamente, quiero detectar cuando un mouse ha hecho clic en la imagen, y luego mover la imagen hacia la izquierda, derecha, arriba o abajo junto con el mouse.

En este momento, básicamente tengo una clase MouseFilter que detecta eventos y hace cosas diferentes según el tipo de evento. Adjunté a ese oyente al objeto QGraphicsView

Respuesta

11

QGraphicsView tiene compatibilidad incorporada para el barrido del mouse. Establezca el DragMode correcto y se encargará del resto. Necesitas las barras de desplazamiento de habilitación para que funcione.

+0

¿Crees que podría implementar esto por mi cuenta? Quiero hacer esto presionando el botón derecho del mouse. ¿Cómo puedo desplazar la vista desde el código? – neuviemeporte

+0

@neuviemeporte: No sé cómo hacerlo con el botón derecho del mouse. Es posible que desee publicarlo como una pregunta separada para que alguien más pueda responderlo. –

+0

Ya no tiene que habilitar las barras de desplazamiento en Qt 5.0 – vsz

39

En caso de que alguien se pregunte cómo hacerlo por su cuenta, en realidad es bastante simple. Aquí está el código de mi aplicación:

class ImageView : public QGraphicsView 
{ 
public: 
    ImageView(QWidget *parent); 
    ~ImageView(); 

private: 
    virtual void mouseMoveEvent(QMouseEvent *event); 
    virtual void mousePressEvent(QMouseEvent *event); 
    virtual void mouseReleaseEvent(QMouseEvent *event); 

    bool _pan; 
    int _panStartX, _panStartY; 
}; 

Necesita almacenar la posición inicial de la resistencia, por ejemplo como este (que utiliza el botón de la derecha):

void ImageView::mousePressEvent(QMouseEvent *event) 
{ 
    if (event->button() == Qt::RightButton) 
    { 
     _pan = true; 
     _panStartX = event->x(); 
     _panStartY = event->y(); 
     setCursor(Qt::ClosedHandCursor); 
     event->accept(); 
     return; 
    } 
    event->ignore(); 
} 

Además, es necesario borrar la bandera y restaurar el cursor una vez que se suelta el botón:

void ImageView::mouseReleaseEvent(QMouseEvent *event) 
{ 
    if (event->button() == Qt::RightButton) 
    { 
     _pan = false; 
     setCursor(Qt::ArrowCursor); 
     event->accept(); 
     return; 
    } 
    event->ignore(); 
} 

para administrar efectivamente el arrastre, es necesario anular el desplazamiento del ratón. QGraphicsView hereda un QAbstractScrollArea, y sus barras de desplazamiento son de fácil acceso. También debe actualizar la posición panorámica:

void ImageView::mouseMoveEvent(QMouseEvent *event) 
{ 
    if (_pan) 
    { 
     horizontalScrollBar()->setValue(horizontalScrollBar()->value() - (event->x() - _panStartX)); 
     verticalScrollBar()->setValue(verticalScrollBar()->value() - (event->y() - _panStartY)); 
     _panStartX = event->x(); 
     _panStartY = event->y(); 
     event->accept(); 
     return; 
    } 
    event->ignore(); 

} 
+0

simplemente brillante –

+0

Gracias por el código, ¡muy útil! – enriched

+0

sí, exactamente lo que estaba buscando ... ¡incluso años más tarde, gracias! – Amazonasmann

2

La solución neuviemeporte requiere que la subclase QGraphicsView.

Se puede obtener otra implementación de arrastre de trabajo sin crear subclases de la vista con eventFilter. Si no necesita personalizar otros comportamientos de QGraphicsView, esta técnica le ahorrará trabajo.

Digamos que la lógica de su GUI se mantiene mediante una subclase QMainWindow y QGraphicsView & QGraphicsScene se declaran como miembros privados de esta subclase. Usted tendría que implementar la función EventFilter de la siguiente manera:

bool MyMainWindow::eventFilter(QObject *obj, QEvent *event) 
{ 
    if (obj == scene && event->type() == Event::GraphicsSceneMouseMove) 
    { 
     QGraphicsSceneMouseEvent *m = static_cast<QGraphicsSceneMouseEvent*>(event); 
     if (m->buttons() & Qt::MiddleButton) 
     { 
      QPointF delta = m->lastScreenPos() - m->screenPos(); 
      int newX = view->horizontalScrollBar()->value() + delta.x(); 
      int newY = view->verticalScrollBar()->value() + delta.y(); 
      view->horizontalScrollBar()->setValue(newX); 
      view->verticalScrollBar()->setValue(newY); 
      return true; 
     } 
    } 

    return QMainWindow::eventFilter(obj, event); 
} 

Para filtrar los eventos de la QGraphicsScene, usted tiene que instalar MyMainWindow como EventFilter de la escena. Quizás podría hacer esto en la misma función donde configura su GUI.

void MyMainWindow::setupGUI() 
{ 
    // along with other GUI stuff... 

    scene->installEventFilter(this); 
} 

Puede ampliar esta idea para reemplazar el cursor con la "mano" arrastrar como se muestra anteriormente.

Cuestiones relacionadas