文章学习自:
Qt_绘图框架_QGraphicsview实现缩放移动图片_Livy0123的博客-CSDN博客
这里进行一些自己的分析和理解。
(1)
自定义类MyGraphicsView继承自QGraphicsView
核心是重定义的滚轮事件。
void MyGraphicsView::wheelEvent(QWheelEvent *ev)
{if(Qt::CTRL == ev->modifiers()) //键盘CTRL键{if(ev->delta() > 0){qrTmp = 1.2;this->scale(qrTmp,qrTmp);}else{qrTmp = 1.0/1.2;this->scale(qrTmp,qrTmp);}m_qrScaledNum *= qrTmp; //保存放大倍数}
}
实现功能是:通过转动滚轮,放大或缩小view,进而形成这样的视觉效果。
相关知识:
ev->modifiers();
返回可能伴随wheel事件的键盘修饰符。
Constant
Value
Qt3DInput::QWheelEvent::NoModifier
Qt::NoModifier
Qt3DInput::QWheelEvent::ShiftModifier
Qt::ShiftModifier
Qt3DInput::QWheelEvent::ControlModifier
Qt::ControlModifier
Qt3DInput::QWheelEvent::AltModifier
Qt::AltModifier
Qt3DInput::QWheelEvent::MetaModifier
Qt::MetaModifier
Qt3DInput::QWheelEvent::KeypadModifier
Qt::KeypadModifier
enum Modifier {META = Qt::MetaModifier,SHIFT = Qt::ShiftModifier,CTRL = Qt::ControlModifier,ALT = Qt::AltModifier,MODIFIER_MASK = KeyboardModifierMask,UNICODE_ACCEL = 0x00000000};
ev->delta();
每当滚轮转动一下,默认是15度
这时调用QWheelEvent()::delta()返回的值就是15*8=120。
ev->delta(); //滑动的距离 //向下滑动为负值 //向上滑动为正值
(2)
这个动图中,无法实现随着鼠标的移动,放大那个区域的图像。
而下面这个动图可以。
关键代码:
this->setMouseTracking(true); //跟踪鼠标位置//这两句的作用://以鼠标中心点为锚点setTransformationAnchor(QGraphicsView::AnchorUnderMouse);setResizeAnchor(QGraphicsView::AnchorUnderMouse);
(3)初始化MyGraphicsView对象和QGraphicsScene对象。
//创建视图this->m_pView = new MyGraphicsView(this);m_pView->resize(VIEW_MAX_WIDTH,VIEW_MAX_HEIGHT);this->m_nViewWidth = m_pView->width();this->m_nViewHeight = m_pView->height();//创建场景this->m_pScene = new QGraphicsScene(this);//设置场景大小和左上角点坐标this->m_pScene->setSceneRect(0,0,VIEW_MAX_WIDTH,VIEW_MAX_HEIGHT);
(4)创建QGraphicsPixmapItem对象存储图片。
//加载图片QString strFilePath = QFileDialog::getOpenFileName(this,tr("Load a Image!"),"C:/Users/zhengfei6/Desktop/testImage",tr("Images(*.png *.jpg *.bmp)"));if(NULL == strFilePath){cout << "FilePath is Null";return;}//加载图片QPixmap pix;pix.load(strFilePath);QGraphicsPixmapItem *pPixItem = new QGraphicsPixmapItem(pix);pPixItem->setFlag(QGraphicsItem::ItemIsMovable,true);//item可移动
(5)为了显示时直接适应视图,需要调整pPixItem的大小和位置。
//获取缩放比例DisplayModeEnum displayMode = DisplayModeEnum::TOPLEFT; //默认左上顶点显示this->m_qrDefaultShrinkedRatio = GetDefaultRatio(pix,displayMode);pPixItem->setScale(1/this->m_qrDefaultShrinkedRatio);//调整item大小,实际上,图像大小是没有变的。
程序作用:
返回值 :图像的伸缩比例。
displayMode:
三种显示模式:
宽度>高度
高度>宽度
pos=(0,0)
qreal MyWidget::GetDefaultRatio(const QPixmap &pix,DisplayModeEnum &displayMode)
{qreal dResRatio = 0;qreal qrWidthRatio = (qreal)pix.width()/(qreal)VIEW_MAX_WIDTH;qreal qrHeightRatio = (qreal)pix.height()/(qreal)VIEW_MAX_HEIGHT;cout << "qrWidthRatio = "<< qrWidthRatio;cout << "qrHeightRatio = "<< qrHeightRatio;qreal nMaxTmp = qMax(qrWidthRatio,qrHeightRatio); //取宽宽比和高高比的大者//举例:pix(1080,600),view(1080,400)//1,1.5//为了成功放下这张图片,需要调整图片大小为(1080*2/3,600*2/3)//宽调整为一致,看高,如果pix更大,放弃//高调整为一致,看宽,如果pix更大,放弃// cout << "nMaxTmp = "<< nMaxTmp;if(qrWidthRatio == nMaxTmp)//宽宽比>高高比{dResRatio = qrWidthRatio;displayMode = DisplayModeEnum::YVerticalMiddle;//Y垂直轴居中}else//宽高比<=高高比{dResRatio = qrHeightRatio;displayMode = DisplayModeEnum::XHorizontalMiddle;//X水平轴居中}//cout << "dResRatio = "<< dResRatio;return dResRatio;
}