天空闲话 发表于 2024-6-11 13:50:40

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

一、QGraphicsView相关整理

项目中频仍地使用了QGraphicsView相关的类
(1)继续QGraphicsView,改写下面的protected成员函数进行自界说操作:
protected:
    void keyPressEvent(QKeyEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void paintEvent(QPaintEvent * event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseDoubleClickEvent(QMouseEvent *event);
    void wheelEvent(QWheelEvent *event);
使用中注意,如果想使QGraphicsView中已界说的操作任然有效,则需要在函数界说代码中添加下列语句, 以便实现父类已经是实现的默认操作。
QGraphicsView::keyPressEvent(event);
QGraphicsView::mousePressEvent(event);
QGraphicsView::mouseMoveEvent(event);
QGraphicsView::paintEvent(event);
QGraphicsView::mouseDoubleClickEvent(event);
QGraphicsView::wheelEvent(event);
(2) 可创建QGraphicsScene对象添加到QGraphicsView对象中(setScene(QgraphicsScene* scene)),可以使用同样的方法继续QGraphicsScene进行自界说操作;
(3) QGraphicsView中有**horizontalScrollBar()和verticalScrollBar()**可以返回视图中的滚动条,下面的代码可以设置滚动条的表现模式
m_graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

// 设置在视图中进行拖动
setDragMode(QGraphicsView::ScrollHandDrag);
(4)当使用自界说的右键选择菜单时,需要下面的语句,在槽函数on_graphicsView_customContextMenuRequested(QPoint) 中界说相关操作
m_graphicsView->setContextMenuPolicy (Qt::CustomContextMenu);
    connect(m_graphicsView,SIGNAL(customContextMenuRequested(QPoint)),this, SLOT(on_graphicsView_customContextMenuRequested(QPoint)));
(5)QGraphicsItem相关:
QGraphicsTextItem, QGraphicsLineItem, QGraphicsRectItem 三个Graphicsitem
QGraphicsTextItem *title = new QGraphicsTextItem();
title->setPlainText(name);
title->setPos(10, 10);
title->setFont(QFont(QString::fromLocal8Bit ("楷体"),15));
title->setDefaultTextColor(QColor(160, 160, 160));
title->setZValue(30);//设置图层

QGraphicsLineItem *linetemp = new QGraphicsLineItem();
QPen pen = linetemp->pen();
pen.setColor(QColor(81, 82, 84));
pen.setWidth(4);
linetemp->setPen(pen);
linetemp->setLine(QLineF(0, 0, 10,10));
linetemp->setZValue (12);

QGraphicsRectItem* m_overAreaTop = new QGraphicsRectItem();
m_overAreaTop->setRect(0,0,10,10);
m_overAreaTop->setBrush(QBrush(QColor(64, 66, 68)));//填充色
m_overAreaTop->setPen(QPen(QColor(64, 66, 68)));//边框线
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中实现的
void QCustomQGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent * e)
{
        //TODO:鼠标左键,点击绘制图形;鼠标右键,点击拖动图形
        QGraphicsScene::mousePressEvent(e);
        if (e->button() & Qt::LeftButton){
      //当图形处于绘制状态时, 记录鼠标按下的点
                if (m_enumShape!= Drawing_Normal) m_vetPoints.push_back(e->scenePos());
        }
}
2.3 实时获取鼠标最新位置并绘图

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


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

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

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


[*]QGraphicsView::NoDrag,
[*]QGraphicsView::RubberBandDrag
[*]QGraphicsView::ScrollHandDrag
MyGraphicsView::MyGraphicsView()
{
    //设置ui控件属性
    setDragMode(QGraphicsView::NoDrag);
    scale_m = 1;                              //图形原始比例
    setStyleSheet("padding: 0px; border: 0px;");//无边框
    setMouseTracking(true);                  //跟踪鼠标位置
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//隐藏水平条
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);    //隐藏竖条
    setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
    setResizeAnchor(QGraphicsView::AnchorUnderMouse);
   
}
void MyGraphicsView::wheelEvent ( QWheelEvent * event )
{
    if (event->modifiers() == Qt::CTRL){                  //按住ctrl键 可以放大缩小
      if((event->delta() > 0)&&(scale_m >= 50)) return; //最大放大到原始图像的50倍

                // 图像缩小到自适应大小之后就不继续缩小; 重置图片大小和位置,使之自适应控件窗口大小
      else if((event->delta() < 0)&&(scale_m <= 0.01)) return;
      else
      {
            // 当前放缩倍数;
            qreal scaleFactor = this->matrix().m11();
            scale_m = scaleFactor;
            int wheelDeltaValue = event->delta();
            if (wheelDeltaValue > 0) this->scale(1.2, 1.2); // 向上滚动,放大;
            else this->scale(1.0 / 1.2, 1.0 / 1.2);         // 向下滚动,缩小;
            update();
      }
    }   
}
QPainter鼠标绘制矩形,多边形:https://blog.csdn.net/Stone_OverLooking/article/details/112886734

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Qt(十二)Graphics View 绘图架构(三)