2013-06-28 80 views
1

我被这种奇怪的行为卡住,如果我启用橡皮筋拖动,车轮事件不会在鼠标下缩放了。它可以缩放,但与鼠标位置无关。如果我禁用其他事件,那么wheelEvent可以正常工作。QgraphicsView橡皮筋效果缩放行为

我有一个自定义的类继承的QGraphicsView为:

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); 

}; 

构造:

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); 
} 

事件处理程序:

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(); 
    } 
} 
*/ 

任何想法,我做错了什么或怎么办我修复它 ?

+0

你知道'graphicsView-> setDragMode(QGraphicsView :: RubberBandDrag)'吗?看起来你正在尝试实施已经实施的内容。 –

+0

是的,我知道这件事。但是对于橡皮筋,我想选择一个带橡皮筋的区域,并在选定区域填充整个屏幕。我不知道如何通过执行'setDragMode(QGraphicsView :: RubberBandDrag)'来继续。这就是为什么我实现了一个自定义的橡皮筋过程。 – gaganbm

+0

我不明白这个问题,但试着用单独问题中的更多细节来描述它。可能是这个问题有一个解决方案,你不必重新实现橡皮筋。 –

回答

1

QGraphicsView::scale函数的行为取决于鼠标位置。它由QGraphicsView自动和内部执行。由于您不会将鼠标位置传递给scale函数,因此我认为QGraphicsView会跟踪鼠标并自行记住最后一个位置。

通过重新实现鼠标事件处理函数,您已经从中获取了该能力。视图不能再决定鼠标的位置,因为它的原始处理程序没有被调用。

幸运的是,这个问题可以很容易地修复。您需要自己来调用基类实现:

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

这对mousePressEvent一个例子,但除非你需要禁用的默认行为的一些部分,你应该增加类似的语句来你的所有事件处理程序。

+0

谢谢!这样一个简单的解决方案,但我无法找到在网上的任何文档! – gaganbm