Qt(十二)Graphics View 绘图架构(三)

打印 上一主题 下一主题

主题 537|帖子 537|积分 1611

一、QGraphicsView相关整理

项目中频仍地使用了QGraphicsView相关的类
(1)继续QGraphicsView,改写下面的protected成员函数进行自界说操作:
  1. protected:
  2.     void keyPressEvent(QKeyEvent *event);
  3.     void mousePressEvent(QMouseEvent *event);
  4.     void paintEvent(QPaintEvent * event);
  5.     void mouseMoveEvent(QMouseEvent *event);
  6.     void mouseDoubleClickEvent(QMouseEvent *event);
  7.     void wheelEvent(QWheelEvent *event);
复制代码
使用中注意,如果想使QGraphicsView中已界说的操作任然有效,则需要在函数界说代码中添加下列语句, 以便实现父类已经是实现的默认操作。
  1. QGraphicsView::keyPressEvent(event);
  2. QGraphicsView::mousePressEvent(event);
  3. QGraphicsView::mouseMoveEvent(event);
  4. QGraphicsView::paintEvent(event);
  5. QGraphicsView::mouseDoubleClickEvent(event);
  6. QGraphicsView::wheelEvent(event);
复制代码
(2) 可创建QGraphicsScene对象添加到QGraphicsView对象中(setScene(QgraphicsScene* scene)),可以使用同样的方法继续QGraphicsScene进行自界说操作;
(3) QGraphicsView中有**horizontalScrollBar()verticalScrollBar()**可以返回视图中的滚动条,下面的代码可以设置滚动条的表现模式
  1. m_graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  2. m_graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  3. // 设置在视图中进行拖动
  4. setDragMode(QGraphicsView::ScrollHandDrag);
复制代码
(4)当使用自界说的右键选择菜单时,需要下面的语句,在槽函数on_graphicsView_customContextMenuRequested(QPoint) 中界说相关操作
  1. m_graphicsView->setContextMenuPolicy (Qt::CustomContextMenu);
  2.     connect(m_graphicsView,SIGNAL(customContextMenuRequested(QPoint)),this, SLOT(on_graphicsView_customContextMenuRequested(QPoint)));
复制代码
(5)QGraphicsItem相关:
QGraphicsTextItem, QGraphicsLineItem, QGraphicsRectItem 三个Graphicsitem
  1. QGraphicsTextItem *title = new QGraphicsTextItem();
  2. title->setPlainText(name);
  3. title->setPos(10, 10);
  4. title->setFont(QFont(QString::fromLocal8Bit ("楷体"),15));
  5. title->setDefaultTextColor(QColor(160, 160, 160));
  6. title->setZValue(30);//设置图层
  7. QGraphicsLineItem *linetemp = new QGraphicsLineItem();
  8. QPen pen = linetemp->pen();
  9. pen.setColor(QColor(81, 82, 84));
  10. pen.setWidth(4);
  11. linetemp->setPen(pen);
  12. linetemp->setLine(QLineF(0, 0, 10,  10));
  13. linetemp->setZValue (12);
  14. QGraphicsRectItem* m_overAreaTop = new QGraphicsRectItem();
  15. m_overAreaTop->setRect(0,0,10,10);
  16. m_overAreaTop->setBrush(QBrush(QColor(64, 66, 68)));//填充色
  17. m_overAreaTop->setPen(QPen(QColor(64, 66, 68)));//边框线
  18. m_overAreaTop->setZValue(10);
复制代码
每个item设置ZValue可以在对象重适时选择表现哪个对象表现在最前面。
可以通过boundingRect()获取item的边界框QRect类对象,并可以通过mapFromGlobal、mapRectToParent、mapRectToScene等进行坐标转换,末了通过QRect的contains()判断相关点的包罗问题。
二、QGraphicsView架构下实时鼠标绘制图形

2.1 鼠标拖拽绘图说明

想要实现鼠标拖拽绘图的结果,离不开鼠标的三大事件:按下移动开释
   绘制矩形框的核心流程
第一步:鼠标左键点击,记录初始点击位置
第二步:在窗口中移动鼠标,实时获取鼠标拖动点,根据拖动点绘制指定形状
第三步:鼠标点击右键开释鼠标,绘制终极图形
  在进行鼠标点击绘制的时候,为了兼容多个图形的实时绘制,这里,不只是用两个QPoint成员变量记录鼠标点,而是采取了vector<QPontF>容器存储的方式。
比方:三角形图形,需要三个点才气确定图形;曲线图形,是由N多个点才气确定图形;等等…
图形枚举类型 枚举类型 形状
Drawing_Normal无图形绘制
Drawing_Circular 圆形
Drawing_StraightLine 直线
Drawing_Rectangular 矩形
Drawing_Triangle 三角形
Drawing_ManyLineSegements多线段
Drawing_Curve 曲线
2.2 记录图形第一个绘制点

这里以Drawing_Rectangular为例
鼠标点击后才气获取当前点击点的位置,记录按下点操作应该是在鼠标的mousePressEvent中实现的
  1. void QCustomQGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent * e)
  2. {
  3.         //TODO:鼠标左键,点击绘制图形;鼠标右键,点击拖动图形
  4.         QGraphicsScene::mousePressEvent(e);
  5.         if (e->button() & Qt::LeftButton){
  6.         //当图形处于绘制状态时, 记录鼠标按下的点
  7.                 if (m_enumShape!= Drawing_Normal) m_vetPoints.push_back(e->scenePos());
  8.         }
  9. }
复制代码
2.3 实时获取鼠标最新位置并绘图

鼠标想要实时绘制,在移动鼠标的mouseMoveEvent事件中操作的。
  1. void QCustomQGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent * e)
  2. {
  3.         //TODO:鼠标移动时,如果存在有效图形类型,进行图形绘制
  4.         QGraphicsScene::mouseMoveEvent(e);
  5.         if (m_enumShape!= Drawing_Normal)
  6.         {
  7.          m_pTempLayer->DrawShape(m_enumShape, m_vetPt, e->scenePos());
  8.         }
  9. }
复制代码
DrawShape函数 的解说


  • 参数1:图形的枚举类型,根据差别枚举,绘制差别的图形
  • 参数2:vector<QPointF>传入已经记录的鼠标点,可以是多个,但最少是1个。就比方当前绘制矩形来说,该容器中只是存储了一个绘制点。
  • 参数3:鼠标在mouseMoveEvent中实时拖动点
    DrawShape函数实现代码,如下:
  1. void QTempCanvasLayer::DrawShape(ENUM_DrawingGraphic enumShape, std::vector<QPointF> vetPt, QPointF ptCurrent)
  2. {
  3.         m_pTempCanvasImg->fill(Qt::transparent);  //避免拖动鼠标绘制图形时,线条重叠
  4.         m_pTempPainter->setRenderHint(QPainter::Antialiasing, true);
  5.         m_pTempPainter->setCompositionMode(QPainter::CompositionMode_Source);
  6.         m_pTempPainter->setPen(QPen(QColor(51, 51, 51), 1, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin));
  7.         switch (enumShape)
  8.         {
  9.         case Drawing_Circular:          //圆形
  10.                 break;
  11.         case Drawing_StraightLine:      //直线
  12.                 break;
  13.         case Drawing_Rectangular:       //矩形
  14.                 m_pTempPainter->drawRect(QRectF(vetPt[0], ptCurrent));
  15.                 break;
  16.         case Drawing_Triangle:          //三角形
  17.                 break;
  18.         case Drawing_ManyLineSegements: //多线段
  19.                 break;
  20.         case Drawing_Curve:             //曲线
  21.                 break;
  22.         default:
  23.                 break;
  24.         }
  25.         update();
  26. }
复制代码
2.4 开释绘制点,绘制终极图形

鼠标事件:mouseReleaseEvent 绘制鼠标
  1. void QCustomQGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent * e)
  2. {
  3.         //TODO:鼠标释放之后操作
  4.         QGraphicsScene::mouseReleaseEvent(e);
  5.         if (m_enumShape == Drawing_Normal) return;
  6.        
  7.         //存在有效的图形类型,进行最终图形绘制
  8.         if (e->button() & Qt::RightButton){
  9.                 if (m_enumShape == Drawing_Rectangular){
  10.                         //绘制直线,需要存储两个有效点
  11.                         if (m_vetPt.size() == 2){
  12.                                 this->DrawRealShape(m_vetPt);
  13.                                 this->ClearCurrentDrawingShape();   //如果当前正在绘制图形,直接清除
  14.                         }
  15.                 }
  16.         }
  17. }
复制代码
三、QGraphicsView 在鼠标点击处进行放大缩小

使用QGraphicsView类的设置属性函数.在构造函数中增加下面两个函数即可。
  1. ui->View_ImageOpro->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
  2. ui->View_ImageOpro->setResizeAnchor(QGraphicsView::AnchorUnderMouse);
复制代码
setDragMode枚举值:


  • QGraphicsView::NoDrag,
  • QGraphicsView::RubberBandDrag
  • QGraphicsView::ScrollHandDrag
  1. MyGraphicsView::MyGraphicsView()
  2. {
  3.     //设置ui控件属性
  4.     setDragMode(QGraphicsView::NoDrag);
  5.     scale_m = 1;                                //图形原始比例
  6.     setStyleSheet("padding: 0px; border: 0px;");//无边框
  7.     setMouseTracking(true);                    //跟踪鼠标位置
  8.     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);  //隐藏水平条
  9.     setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);    //隐藏竖条
  10.     setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
  11.     setResizeAnchor(QGraphicsView::AnchorUnderMouse);
  12.    
  13. }
  14. void MyGraphicsView::wheelEvent ( QWheelEvent * event )
  15. {
  16.     if (event->modifiers() == Qt::CTRL){                  //按住ctrl键 可以放大缩小
  17.         if((event->delta() > 0)&&(scale_m >= 50)) return; //最大放大到原始图像的50倍
  18.                 // 图像缩小到自适应大小之后就不继续缩小; 重置图片大小和位置,使之自适应控件窗口大小
  19.         else if((event->delta() < 0)&&(scale_m <= 0.01)) return;
  20.         else
  21.         {
  22.             // 当前放缩倍数;
  23.             qreal scaleFactor = this->matrix().m11();
  24.             scale_m = scaleFactor;
  25.             int wheelDeltaValue = event->delta();
  26.             if (wheelDeltaValue > 0) this->scale(1.2, 1.2); // 向上滚动,放大;
  27.             else this->scale(1.0 / 1.2, 1.0 / 1.2);         // 向下滚动,缩小;
  28.             update();
  29.         }
  30.     }   
  31. }
复制代码
QPainter鼠标绘制矩形,多边形:https://blog.csdn.net/Stone_OverLooking/article/details/112886734

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

天空闲话

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表