#include "graphicsItem/electricSvgItem.h" #include "graphicsItem/itemControlHandle.h" #include #include #include #include ElectricSvgItem::ElectricSvgItem(const QRect &rect, QGraphicsItem *parent) : GraphicsBaseItem(parent),m_pRender(nullptr) { m_lastBoudingRect = rect; m_boundingRect = rect; m_dWidth = rect.width(); m_dHeight = rect.height(); } ElectricSvgItem::~ElectricSvgItem() { } QPainterPath ElectricSvgItem::shape() { QPainterPath path; double dHandleX = 0.0; double dHandleY = 0.0; path.addRect(m_boundingRect); return path; } void ElectricSvgItem::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(); //将boundingRect设置成中心点和原点(也是默认变换原点),这样三点重合,有助于简化计算 m_boundingRect = QRectF(-m_dWidth / 2, -m_dHeight / 2, m_dWidth, m_dHeight); //setTransformOriginPoint(m_boundingRect.center()); //变换中心默认为item的(0,0)点,所以不执行这句话也没有问题 //更新bouondingRect后重回会显示位置会有变化,需要做对应的移动 moveBy(-delta.x(), -delta.y()); updateHandles(); } m_lastBoudingRect = m_boundingRect; } void ElectricSvgItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { if(m_pRender) { m_pRender->render(painter,m_boundingRect); } painter->setPen(m_pen); painter->setBrush(m_brush); if(m_state == S_lineOut) { painter->setPen(QPen(QColor(255,51,153,180))); painter->drawLine(m_beginConnectPoint,m_endConnectPoint); } if (option->state & QStyle::State_Selected) //是选中状态,绘制选中框 { int nPenWidth = 1; painter->setPen(QPen(QColor(135,206,235,180))); //蓝色的外框 painter->setBrush(QBrush(QColor(135,206,235,180))); double dx = m_boundingRect_selected.x(); double dy = m_boundingRect_selected.y(); double dWidth = m_boundingRect_selected.width(); double dHeight = m_boundingRect_selected.height(); //画弧线0度是3点钟方向 if(dWidth > dHeight) { painter->drawRect(m_boundingRect_selected); painter->drawChord(dx-dHeight*0.5,dy,dHeight,dHeight,90*16,180*16); painter->drawChord(dx+dWidth-dHeight*0.5,dy,dHeight,dHeight,(-90)*16,180*16); } else if(dWidth < dHeight) { painter->drawRect(m_boundingRect_selected); painter->drawChord(dx,dy-dWidth*0.5,dWidth,dWidth,0*16,180*16); painter->drawChord(dx,dy+dHeight-dWidth*0.5,dWidth,dWidth,180*16,180*16); //painter->drawChord(dx+dWidth-dHeight*0.5,dy,dHeight,dHeight,(-90)*16,180*16); } else { painter->drawEllipse(QPointF(dx+dWidth*0.5,dy+dHeight*0.5),dHeight*0.5,dHeight*0.5); } //绘制变换原点 QPointF originPoint = transformOriginPoint(); //qDebug() << "originPoint:" << originPoint; painter->setBrush(Qt::red); painter->drawEllipse(originPoint, 4, 4); } } void ElectricSvgItem::loadSvg(const QString& str) { m_pRender = new QSvgRenderer(str); } void ElectricSvgItem::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_boundingRect = trans.mapRect(m_lastBoudingRect); m_dWidth = m_boundingRect.width(); m_dHeight = m_boundingRect.height(); updateHandles(); } void ElectricSvgItem::move(const QPointF& point) { moveBy(point.x(), point.y()); } void ElectricSvgItem::editShape(int nHandle,const QPointF& ptMouse) { prepareGeometryChange(); updateHandles(); }