#include "graphicsItem/graphicsPolygonItem.h" #include "graphicsItem/itemControlHandle.h" #include GraphicPolygonItem::GraphicPolygonItem(QGraphicsItem *parent) : GraphicsBaseItem(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() { GraphicsBaseItem::updateHandles(); for(int i = 0; i < m_points.size(); i++) { m_vecHanle[H_edit + i -1]->move(m_points[i].x(), m_points[i].y()); } } void GraphicPolygonItem::updateCoordinate() //当执行了resie和editShape函数后,boundingRect发生了变换,需要将item的原点(以中心点为原点)校准至boundingRect.center() { QPointF pt1, pt2, delta; pt1 = mapToScene(QPointF(0, 0)); pt2 = mapToScene(m_boundingRect.center()); delta = pt1 - pt2; if (!parentItem()) { prepareGeometryChange(); //更改图形绘制节点坐标,让图形中心和原点对齐 for(int i=0; isetPen(m_pen); painter->setBrush(m_brush); painter->drawPolygon(m_points); } 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_left - 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 ItemControlHandle(this); pHandle->setType(T_editShape); pHandle->setTag(H_edit + nCount - 1); m_vecHanle.push_back(pHandle); } bool GraphicPolygonItem::endDrawing() { bool bSuccess = true; int nPointCount = m_points.count(); if(nPointCount < 3) bSuccess = false; return bSuccess; }