Qt鼠标拖动绘制基本几何图形

概述

用Qt鼠标事件实现基本几何图形的绘制,支持直线、矩形、圆形、椭圆。后期可以在此基础上进行扩展。

效果图

Qt鼠标拖动绘制基本几何图形_第1张图片

实现

本示例使用QGraphics体系来实现,因为要移动对象,所以生成的图形必须是一个单独的对象,鼠标拖动绘制的过程是在临时层中完成,release后生成一个矢量的图形item并添加到场景中。

关键代码

主场景中有一个父rootItem,在scene中将鼠标或触控事件传到rooitem后动态绘制临时的图形,release事件后生成一个标准的图形对象:

void GsRootItem::drawPress(int id, const QPointF &p)
{
    ShapeInfo info;
    info.firstPos = p;
    info.type = getCurType();
    m_Objs.insert(id,info);
}

void GsRootItem::drawMove(int id, const QPointF &lastPoint, const QPointF &curPoint)
{
    if(!m_Objs.contains(id)){
        return;
    }
    ShapeInfo info = m_Objs.value(id);
    m_pTempLayer->drawShape(info.type,info.firstPos,curPoint);
}

void GsRootItem::drawRelease(int id, const QPointF &point)
{
    if(!m_Objs.contains(id)){
        return;
    }
    ShapeInfo info = m_Objs.value(id);
    drawRealShape(info.type,info.firstPos,point);
    m_Objs.remove(id);
    m_pTempLayer->clear();
}

...
void GsRootItem::drawRealShape(GsShapeType type, QPointF p1, QPointF p2)
{
    //计算图形绘制区域
    QRectF rect;
    rect.setX(qMin(p1.x(),p2.x()));
    rect.setY(qMin(p1.y(),p2.y()));
    if(type == Shape_Circle){
        rect.setWidth(qAbs(p1.y() - p2.y()));
        rect.setHeight(qAbs(p1.y() - p2.y()));
    }
    else{
        rect.setWidth(qAbs(p1.x() - p2.x()));
        rect.setHeight(qAbs(p1.y() - p2.y()));
    }
    rect.adjust(-5,-5,5,5);
    GsShapeBaseItem * item = m_pShapeFactory->getShapeItem(type,rect,this);
    item->drawShape(p1,p2);
}

drawRealShape函数就是用与创建一个独立的几何图形,通过以下的工厂模式来生成

 GsShapeBaseItem * item = m_pShapeFactory->getShapeItem(type,rect,this);

工厂代码:

GsShapeBaseItem *GsShapeFactory::getShapeItem(GsShapeType type,QRectF rectF,
                                              QGraphicsObject *parent)
{
    GsShapeBaseItem * item = nullptr;
    switch (type) {
    case Shape_Line:
        item = new GsShapeLineItem(rectF,parent);
        break;
    case Shape_Rectange:
        item = new GsShapeRectangeItem(rectF,parent);
        break;
    case Shape_Circle:
        item = new GsShapeCircleItem(rectF,parent);
        break;
    case Shape_Oval:
        item = new GsShapeOvalItem(rectF,parent);
        break;
    default:
        break;
    }
    item->setZValue(10);
    return item;
}

在工厂类中会创建不同的图形对象。每一个图形对象是继承于QGraphicsObject然后重写paint函数去进行绘制,比如说原型:

void GsShapeCircleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->setRenderHint(QPainter::Antialiasing);
    QColor color = Qt::red;//(rand()%255,rand()%255,rand()%255);
    painter->setBrush(color);
    if(m_bTap){
        painter->setPen(QPen(Qt::yellow,5,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
    }
    else{
        painter->setPen(QPen(color,3,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
    }
    painter->drawEllipse(m_firstPoint.x(),m_firstPoint.y(),
                         qAbs(m_lastPoint.y() - m_firstPoint.y()),
                         qAbs(m_lastPoint.y() - m_firstPoint.y()));
}

其他图形类似。

实现图形的选择和拖动,需要在item中添加以下两句:

setFlag(ItemIsSelectable,true);
setFlag(ItemIsMovable,true);

然后就可以自由拖动啦。

代码太多, 就不全部列出来了,基本逻辑都很简单。
代码下载地址

github下载

你可能感兴趣的:(Qt,Qt鼠标绘制几何图形,Qt几何图形绘制,几何图形,鼠标绘制)