QgraphicsView 橡皮筋拖动效果缩放行为
Posted
技术标签:
【中文标题】QgraphicsView 橡皮筋拖动效果缩放行为【英文标题】:QgraphicsView rubberbanddrag effects zooming behavior 【发布时间】:2013-06-28 11:45:18 【问题描述】:我被这种奇怪的行为困住了,如果我启用橡皮筋拖动,滚轮事件不再在鼠标下放大。它会缩放,但与鼠标位置无关。如果我禁用其他事件,则 wheelEvent 可以正常工作。
我有一个继承 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();
*/
知道我在哪里做错了或如何解决吗?
【问题讨论】:
你知道graphicsView->setDragMode(QGraphicsView::RubberBandDrag)
吗?您似乎正在尝试实施已经实施的内容。
是的,我知道。但也有橡皮筋,我想用橡皮筋选择一个区域,并用所选区域填充整个屏幕。我不知道如何通过 setDragMode(QGraphicsView::RubberBandDrag)
来进行。这就是我实现自定义橡皮筋拖动过程的原因。
我不明白这个问题,但尝试在单独的问题中用更多细节来描述它。可能这个问题有解决方案,你不必重新实现橡皮筋。
好吧,我不知道要提供什么详细信息。问题很简单。当我评论其他鼠标事件时,wheelevent 缩放效果很好(如谷歌地球),如代码所示。如果我取消注释这些,缩放在轮事件中无法正常工作。
我说的是您在之前的评论中提到的问题:'我想用橡皮筋选择一个区域并按所选区域填充整个屏幕'。
【参考方案1】:
QGraphicsView::scale
函数的行为取决于鼠标位置。它由QGraphicsView
在内部自动执行。由于您没有将鼠标位置传递给 scale
函数,我认为 QGraphicsView
会跟踪鼠标并自行记住最后一个位置。
通过重新实现鼠标事件处理程序,您已经获得了这种能力。视图无法再确定鼠标位置,因为它的原始处理程序没有被调用。
幸运的是,这个问题很容易解决。您需要在自己之前调用基类实现:
void MyGraphics::mousePressEvent(QMouseEvent *event)
QGraphicsView::mousePressEvent(event);
// your implementation goes here
这是mousePressEvent
的示例,但您应该向所有事件处理程序添加类似的语句,除非您需要禁用某些默认行为。
【讨论】:
谢谢!如此简单的解决方案,但我在网上的任何文档中都找不到!以上是关于QgraphicsView 橡皮筋拖动效果缩放行为的主要内容,如果未能解决你的问题,请参考以下文章
取消在微信里面上拉拖动或者下拉拖动看到的空白。(也是什么橡皮筋效果)
QT:我需要通过 QGraphicsScene 获取添加到 QGraphicsView 的图像坐标