#include "graphicsItem/graphicsPolygonItem.h" //#include "graphicsItem/itemControlHandle.h" #include "graphicsItem/handleRect.h" #include #include GraphicPolygonItem::GraphicPolygonItem(QGraphicsItem *parent) : GraphicsProjectModelItem(parent) { m_pen = QPen(Qt::black); m_brush = QBrush(Qt::NoBrush); } GraphicPolygonItem::~GraphicPolygonItem() { } QPainterPath GraphicPolygonItem::shape() { QPainterPath path; path.addPolygon(m_points); path.closeSubpath(); //将路径闭合 return path; } QRectF GraphicPolygonItem::boundingRect() { //m_boundingRect = shape().controlPointRect(); //返回路径中所有点和控制点的矩形,文档介绍比返回精确边界框的boundingRect()函数计算要快 return m_boundingRect; } void GraphicPolygonItem::updateHandles() { GraphicsProjectModelItem::updateHandles(); for(int i = 0; i < m_points.size(); i++) { if(m_vecHanle.contains(H_edit + i -1)) { m_vecHanle[H_edit + i -1]->move(m_points[i].x(), m_points[i].y()); } } } void GraphicPolygonItem::updateCoordinate() //当执行了resie和editShape函数后,boundingRect发生了变换,需要将item的原点(以中心点为原点)校准至boundingRect.center() { if (!parentItem()) { QPointF pt1, pt2, delta; pt1 = mapToScene(QPointF(0, 0)); pt2 = mapToScene(m_boundingRect.center()); delta = pt1 - pt2; prepareGeometryChange(); //更改图形绘制节点坐标,让图形中心和原点对齐 QPolygonF ptsOnScene = mapToScene(m_points); //所有操作都在scene坐标系下进行,然后在还原至item坐标系,否则会有跳转 for(int i=0; isetPen(m_pen); painter->setBrush(m_brush); painter->drawPolygon(m_points); if (option->state & QStyle::State_Selected) //是选中状态,绘制选中框 { int nPenWidth = 1; painter->setPen(QPen(QColor(70,70,70), nPenWidth, Qt::DashLine)); //蓝色的外框 painter->setBrush(Qt::NoBrush); painter->drawRect(m_boundingRect_selected); //绘制变换原点 QPointF originPoint = transformOriginPoint(); painter->setBrush(Qt::red); painter->drawEllipse(originPoint, 4, 4); } } void GraphicPolygonItem::resize(int nHandle,double dSX, double dSY, const QPointF& basePoint) { switch (nHandle) { case H_left: case H_right: dSY = 1; //拖拽的是左点右点,为水平缩放,忽略垂直变化 break; case H_top: case H_bottom: dSX = 1; //拖拽的是顶点底点,为垂直缩放,忽略水平变化 break; default: break; } QTransform trans; //缩放是以图元原点(中心)位置为基准,所以每帧都先移动移动到想要的基准点,缩放之后再移回 trans.translate(basePoint.x(), basePoint.y()); trans.scale(dSX, dSY); trans.translate(-basePoint.x(), -basePoint.y()); prepareGeometryChange(); m_points = trans.map(m_lastPoints); m_boundingRect = m_points.boundingRect(); m_dWidth = m_boundingRect.width(); m_dHeight = m_boundingRect.height(); updateHandles(); } void GraphicPolygonItem::move(const QPointF& point) { moveBy(point.x(), point.y()); } void GraphicPolygonItem::editShape(int nHandle,const QPointF& ptMouse) { QPointF pt = mapFromScene(ptMouse); m_points[nHandle - H_rotate_leftBottom - 1] = pt; prepareGeometryChange(); m_boundingRect = m_points.boundingRect(); m_dWidth = m_boundingRect.width(); m_dHeight = m_boundingRect.height(); m_lastPoints = m_points; updateHandles(); } void GraphicPolygonItem::addPoint(const QPointF& point) { m_points.append(mapFromScene(point)); int nCount = m_points.count(); //每个顶点都可以编辑,所以一个顶点需要编辑handle ItemControlHandle* pHandle = new HandleRect(this); pHandle->setType(T_editShape); pHandle->setTag(H_edit + nCount - 1); m_vecHanle.insert(H_edit + nCount - 1,pHandle); } bool GraphicPolygonItem::endDrawing() { bool bSuccess = true; int nPointCount = m_points.count(); if(nPointCount < 3) bSuccess = false; return bSuccess; }