一.加载显示图片1.1 创建QGraphicsPixmapItem、QGraphicsScene建议使用new创在堆区PixmapItem设为成员变量(避免可能的加载失败)。m_GraphPixItemnewQGraphicsPixmapItem(nullptr);//有几率会崩 oeGraphicsPixmapItemm_GraphPixItem-setTransformationMode(Qt::SmoothTransformation);//缩放无锯齿m_GraphPixItem-setAcceptHoverEvents(true);//鼠标不点击也捕捉鼠标移动事件m_GraphScenenewQGraphicsScene;m_GraphScene-addItem(m_GraphPixItem);ui-graphicsView-setScene(m_GraphScene);QImage imgcvMat2QImage(mat8);m_GraphPixItem-setPixmap(QPixmap::fromImage(img));//推荐放最后避免无图1.2 设置打开时缩放比例(使图像显示略小于控件)A.构造函数中(长宽不为设定值也不建议进行缩放等相关操作fitInView后坐标不符合预期)B.界面展开显示后/resizeEvent函数中:rect() 打开后为控件正常设置宽高(400,560,0,0)不再随缩放改变长宽。Rectf(400,560,0,0)或(400,560,-199,-279)fitInView(sceneRect(),Qt::KeepAspectRatio);//方式一QRectF boundsscene-itemsBoundingRect();//图1000x1400 Rectf(400,560,-199,-279)bounds.setWidth(bounds.width()*1.);// to tighten-up marginsbounds.setHeight(bounds.height()*1.);// same as aboveui-graphicsView-fitInView(bounds,Qt::KeepAspectRatio);//Rectf(1015,1421,-5,-7)//ui-graphicsView-setSceneRect(bounds);//Rectf(400,560,0,0)//ui-graphicsView-scene()-setSceneRect(bounds);//Rectf(400,560,0,0)ui-graphicsView-centerOn(0,0);//不影响Rectffloattm11this-transform().m11();//查询放大倍数(方便连续加载补偿到初始倍数)1.3 QGraphScene导出为图片voidGraphicsView::ExportSceneSlot(QString sPath){QImageimage(m_GraphScene-width(),m_GraphScene-height(),QImage::Format_ARGB32);//QImage::Format_RGB32QPainterpainter(image);painter.setRenderHint(QPainter::Antialiasing);m_GraphScene-render(painter);QString pngNamesPath/Draw.jpg;boolsaveSuccessimage.save(pngName);Q_ASSERT(saveSuccesstrue);}1.4 属性设置参考默认属性setRenderHint(QPainter::Antialiasing);// 中键拖动平移setDragMode(QGraphicsView::ScrollHandDrag);//该模式下Qt内部会在mouseMoveEvent中自动强制将光标设为OpenHandCursor张开的手掌// 鼠标跟踪用于滚轮缩放时获取鼠标位置setMouseTracking(true);// 设置变换锚点为鼠标位置缩放时以鼠标为中心setTransformationAnchor(QGraphicsView::AnchorUnderMouse);setResizeAnchor(QGraphicsView::AnchorViewCenter);去重影相关QGraphicsView属性setViewportUpdateMode、setRenderHint、setOptimizationFlagssetViewportUpdateMode(QGraphicsView::FullViewportUpdate);//去掉Item可能存在的拖动重影支持拖拽(QWidget支持拖拽事件需设置属性和重写函数。)setAcceptDrops(true);//设置属性voiddragEnterEvent(QDragEnterEvent*event);//拖动进入事件voiddropEvent(QDropEvent*event);voiddragMoveEvent(QDragMoveEvent*event);//连续拖拽QMainWindow嵌入提升的QGraphicsView现象QMainWindow的DragEnterEvent响应DropEvent不响应。目标需要在整个QMainWindow响应dropEvent。解决方式QGraphicsView在QtDesigner中设置AcceptDrops为falseoeGraphicsView设置是否皆可。缩放时QGraphicsPixmapItem锯齿/偏移解决QGraphicsView显示图像文字模糊Qt 图片缩放无锯齿处理m_GraphPixItem-setTransformationMode(Qt::SmoothTransformation);摩尔纹的产生原理二.常用知识点及功能2.1 鼠标事件的传导顺序【view】-【scene分类】-【item】。A.View和Scene同时重写mousePressEvent仅View响应。解决方式在mousePressEvent下调用基类同名函数。voidMyGraphicsView::mousePressEvent(QMouseEvent*e){QGraphicsView::mousePressEvent(e);// forward to scene (via default view behaviour)// ...}B.View重写mousePressEventitem的mousePressEvent响应情况。View加mousePressEventitem的mousePressEvent会响应不加则不会响应。C.mouseMoveEvent函数中提前return导致不按鼠标中心点缩放猜测未将坐标传至scenereturn前加mouseMoveEvent。D.继承QAbstractGraphicsShapeItem时重写虚函数为mouseMoveEvent(QGraphicsmouseMoveEvent )。测面验证【scene分类】-【item】2.2 QGraphicsItem移动/仿射变换QGraphicsItem鼠标拖动(设置属性或重写事件)QTransform transform;//transform.translate(nDistance,0);transform.rotate(90);transform.scale(1,-1);// 垂直翻转ui-graphicsView-m_GraphPixItem-setTransform(transform);QGraphicsItem器件移动及旋转相关问题1.旋转以初始左上角作为固定坐标。2.3 坐标(场景Scene坐标视图View坐标)A.视图坐标(event坐标、控件等)contentsRect();//较rect()两边各减1。viewport();//为控件像素宽width()高height()各-1B.视图坐标转场景坐标event-scenePos();mapToScene(event-pos());//求场景高度//方式一 contentsRect()转Scene再取boundingRect()mapToScene(contentsRect()).boundingRect().height();//sceneRect();//等于图大小C.场景坐标转视图坐标QPointF viewPointthis-matrix().map(m_lastPoint);//Qt5QPointmapFromScene(constQPointFpoint)const;//Qt6D.求QGraphicsScene场景中心QPointF centerscene()-sceneRect().center();//方式一QPointF pfCentermapToScene(rect().center());//方式二QGraphicsView图形视图框架使用(一)坐标变换2.4 鼠标缩放(以鼠标点为中心)//QWheelEvent(angleDelta)。QGraphicsSceneWheelEvent(delta)event-angleDelta;//0.-120其y()正(放大)负值可作为判断是否缩放event-delta;//event-angleDelta.y() Asap用法以鼠标点为中心:A.参考QGraphicsView::centerOnQGraphicsView 如何实现百度地图按照鼠标点进行放大缩小效果(滑动条补偿)B.参考Asap两次centerOnC.设置属性(推荐)setTransformationAnchor(QGraphicsView::AnchorUnderMouse);setResizeAnchor(QGraphicsView::AnchorUnderMouse);QT QGraphicsView 在鼠标点击处进行放大缩小三.进阶3.1 QGraphicsView缓存刷新(QGraphicsItem::CacheModeQPixmapCache)。Qt图形视图框架QGraphicsViewQGraphicsItem::setZValuesetZvalue()来设置一个item的Z值。默认的Z值是0具有同样的Z值的item会按照插入的顺序来入栈(stack order)。也就是说GraphicsView会优先根据item的Z值决定item的层次只有当Z值相同的情况下才会去理会stack orderQt QGraphicsItem的z值怎么用如何确定上下层关系Qt—双缓冲绘图四.异常问题记录4.1 QImage的load加载invalid。解决方法缺少dll库debug下添加imageformats文件夹(本人用的windeployqt生成)。4.2 部分情况加载失败-nan 。1.场景改为成员变量new分配内存猜测该种方式内存分配大、权限高可支持灵活加载大图。2.类似除0这种数字越界。4.3 重写QGraphicsItem。1.需重写纯虚函数boundingRect。2.继承增加QObject和增加Q_OBJECT宏。classUICanvasItemBase:publicQObject,publicQGraphicsItem{Q_OBJECTprotected:QRectFboundingRect()constoverride;voidpaint(QPainter*painter,constQStyleOptionGraphicsItem*option,QWidget*widget)final;}4.4 重写QGraphicsScene的paintEvent(QPaintEvent* event)。1.因父类无paintEvent导致无this指针。4.5 高分辨率屏兼容(contentsRect高度会改变)。放小会调小。屏幕分辨率3840x2160(contentsRect高度1807)。屏幕分辨率1920x1080(contentsRect高度777)。4.6 QDialog中QGraphicsView的move事件不响应。设置二属性ui-graphicsView-setMouseTracking(true);ui-graphicsView-viewport()-installEventFilter(this);4.7 多线程中创建Scene、ItemsetPixmap会运行中断报错:(“bsptreeindexcpp,line348”“unindexedltems.isEmptyO”)。理解QT非gui线程不操作控件相关。4.8 QPixmap先为空加载时setPixmap会以原点镜像翻转4.9 设置鼠标移动样式setDragMode(QGraphicsView::ScrollHandDrag);//该模式下Qt内部会在mouseMoveEvent中自动强制将光标设为OpenHandCursor张开的手掌五.开源示例Draw_Figure(图元绘制及交互)笔记1.重写QAbstractGraphicsShapeItem(继承QGraphicsItem)。2.重写函数(paintboundingRectContextMenu)