1

I am stuck with this weird behavior where, if I enable rubberband drag, the wheel event doesn't zoom under mouse anymore. It does zooming but irrespective of mouse position. And if I disable other events, then wheelEvent works properly.

I have a custom class inheriting QGraphicsView as :

class MyGraphics : public QGraphicsView{

public :
    MyGraphics(QWidget *parent = NULL);

public slots:
     void zoomIn() { scale(1.2, 1.2); }
     void zoomOut() { scale(1 / 1.2, 1 / 1.2); }

protected :
   QRubberBand *rubberBand;
   QPoint       origin;
   QPointF      InitialCenterPoint;
   QPointF      CurrentCenterPoint;
   QPoint       rubberBandOrigin;
   bool         rubberBandActive;
   QPoint       LastPanPoint;
   int          _numScheduledScalings;

//if I uncomment these three event handlers, the wheelevent doesnt zoom properly!

 //  virtual void mousePressEvent(QMouseEvent *event);
 //  virtual void mouseMoveEvent(QMouseEvent *event);
 //  virtual void mouseReleaseEvent(QMouseEvent *event);
   virtual void wheelEvent(QWheelEvent *);
   virtual void resizeEvent(QResizeEvent *event);

};

The constructor :

MyGraphics::MyGraphics(QWidget *parent) : QGraphicsView(parent){
    setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);

    this->installEventFilter(this);
    this->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
    this->setResizeAnchor( QGraphicsView::AnchorUnderMouse );
    QGraphicsScene *graphScene = new QGraphicsScene(this);

    this->setScene(graphScene);
    QGraphicsItem* pEllipse = graphScene->addEllipse(0,100,50,50);
    QGraphicsItem* pRect = graphScene->addRect(200,100,50,50);

    pEllipse->setFlag(QGraphicsItem::ItemIsSelectable, true);
    pRect->setFlag(QGraphicsItem::ItemIsSelectable, true);

    setSceneRect(0, 0, 1000, 1000);
    rubberBandOrigin = QPoint(0,0);
}

Event handlers :

void MyGraphics::wheelEvent(QWheelEvent *event){
    if(event->delta() > 0){
        //Zoom in
        this->zoomIn();
    } else {
        this->zoomOut();
    }

}

/*
void MyGraphics::mousePressEvent(QMouseEvent *event)
{
        if (event->button() == Qt::MiddleButton) {
        rubberBandOrigin = event->pos();
        rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
        rubberBand->setGeometry(event->x(),event->y(),0, 0);
        rubberBand->show();
        rubberBandActive = true;
    }
if(event->button() == Qt::LeftButton){
    LastPanPoint = event->pos();
}


}

void MyGraphics::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() == Qt::MiddleButton && rubberBandActive == true){
        rubberBand->resize( event->x()-rubberBandOrigin.x(), event->y()-rubberBandOrigin.y() );
    }
    else{
        if(!LastPanPoint.isNull()) {
            //Get how much we panned
            QGraphicsView * view = static_cast<QGraphicsView *>(this);

            QPointF delta = view->mapToScene(LastPanPoint) - view->mapToScene(event->pos());
            LastPanPoint = event->pos();
        }
    }
}

void MyGraphics::mouseReleaseEvent(QMouseEvent *event)
{
   if (event->button() == Qt::MiddleButton){
        QGraphicsView * view = static_cast<QGraphicsView *>(this);

        QPoint rubberBandEnd = event->pos();

        QRectF zoomRectInScene = QRectF(view->mapToScene(rubberBandOrigin), view->mapToScene(rubberBandEnd));
        QPointF center = zoomRectInScene.center();

        view->fitInView(zoomRectInScene, Qt::KeepAspectRatio);
        rubberBandActive =  false;
        delete rubberBand;
    }
    else{
        LastPanPoint = QPoint();
    }
}
*/

Any idea where I am doing wrong or how do I fix it ?

4

1 回答 1

1

QGraphicsView::scale函数的行为取决于鼠标位置。它由QGraphicsView. 由于您没有将鼠标位置传递给scale函数,因此我认为QGraphicsView跟踪鼠标并自行记住最后一个位置。

通过重新实现鼠标事件处理程序,您可以从中获得这种能力。视图无法再确定鼠标位置,因为它的原始处理程序没有被调用。

幸运的是,这个问题很容易解决。您需要在自己之前调用基类实现:

void MyGraphics::mousePressEvent(QMouseEvent *event) {
  QGraphicsView::mousePressEvent(event);
  // your implementation goes here
}

这是一个示例,mousePressEvent但您应该向所有事件处理程序添加类似的语句,除非您需要禁用某些默认行为。

于 2013-06-29T19:11:02.350 回答