#ifndef GRAPHICSBASEITEM_H #define GRAPHICSBASEITEM_H #include "itemControlHandle.h" #include #include #include #include //基类采用模板形式,QGraphicsItem是默认值,也可以是别的类型,比如QGraphicsItemGroup,这样不同的基类继承可以共用一些高层的行为定义 template class AbstractShapeType : public BaseType { public: explicit AbstractShapeType(QGraphicsItem *parent = 0) : BaseType(parent) { m_pen = QPen(Qt::NoPen); m_brush = QBrush(QColor(rand() % 32 * 8, rand() % 32 * 8, rand() % 32 * 8)); m_dWidth = m_dHeight = 0; m_pMovingCopy = nullptr; } virtual ~AbstractShapeType() { for (size_t i = 0; i < m_vecHanle.size(); i++) { ItemControlHandle* pHandle = m_vecHanle[i]; if (pHandle) { delete pHandle; pHandle = nullptr; } } } public: QPen pen() { return m_pen; } void setPen(const QPen &pen) { m_pen = pen; } QColor penColor() { return m_pen.color(); } void setPenColor(const QColor &color) { m_pen.setColor(color); } QBrush brush() { return m_brush; } void setBrush(const QBrush &brush) { m_brush = brush; } QColor brushColor() { return m_brush.color(); } void setBrushColor(const QColor &color) { m_brush.setColor(color); } double width() { return m_dWidth; } void setWidth(double width) { m_dWidth = width; updateCoordinate(); } double height() { return m_dHeight; } void setHeight(double height) { m_dHeight = height; updateCoordinate(); } int collidesWithHandle(const QPointF& point) { for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++) { QPointF pt = (*it)->mapFromScene(point); if((*it)->contains(pt)) return (*it)->getTag(); } return HandleTag::H_none; } //移动副本相关 virtual void createMovingCopy() {}; virtual void removeMovingCopy() {}; virtual void moveMovingCopy(const QPointF&) {}; virtual void resize(int,double, double, const QPointF&) {} virtual void move(const QPointF&) {} virtual void editShape(int, const QPointF&) {} virtual void updateCoordinate() {} //handle相关 virtual void setHandleVisible(bool bVisible) { for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++) { if(bVisible) (*it)->show(); else (*it)->hide(); } } virtual QPointF getSymmetricPointPos(int nHandle) //获取对称点的坐标位置,缩放的时候需要以对称点为锚点 { QPointF pt; //编号从1开始,因此下标需要-1 switch (nHandle) { case H_leftTop: pt = m_vecHanle.at(H_rightBottom - 1)->pos(); break; case H_top: pt = m_vecHanle.at(H_bottom - 1)->pos(); break; case H_rightTop: pt = m_vecHanle.at(H_leftBottom - 1)->pos(); break; case H_right: pt = m_vecHanle.at(H_left - 1)->pos(); break; case H_rightBottom: pt = m_vecHanle.at(H_leftTop - 1)->pos(); break; case H_bottom: pt = m_vecHanle.at(H_top - 1)->pos(); break; case H_leftBottom: pt = m_vecHanle.at(H_rightTop - 1)->pos(); break; case H_left: pt = m_vecHanle.at(H_right - 1)->pos(); break; default: break; } return pt; } virtual void updateHandles() { int nMargin = 5; const QRectF& boundRect = this->boundingRect(); for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++) { switch ((*it)->getTag()) { case H_leftTop: (*it)->move(boundRect.x() - nMargin, boundRect.y() - nMargin); break; case H_top: (*it)->move(boundRect.x() + boundRect.width() * 0.5, boundRect.y() - nMargin); break; case H_rightTop: (*it)->move(boundRect.x() + boundRect.width() + nMargin, boundRect.y() - nMargin); break; case H_right: (*it)->move(boundRect.x() + boundRect.width() + nMargin, boundRect.y() + boundRect.height() * 0.5 + nMargin); break; case H_rightBottom: (*it)->move(boundRect.x() + boundRect.width() + nMargin, boundRect.y() + boundRect.height() + nMargin); break; case H_bottom: (*it)->move(boundRect.x() + boundRect.width() * 0.5, boundRect.y() + boundRect.height()+ nMargin); break; case H_leftBottom: (*it)->move(boundRect.x() - nMargin, boundRect.y() + boundRect.height() + nMargin); break; case H_left: (*it)->move(boundRect.x() - nMargin, boundRect.y() + boundRect.height() * 0.5); break; default: break; } } } protected: virtual QRectF boundingRect() const { return m_boundingRect; } virtual QPainterPath shape() { QPainterPath path; return path; } protected: QPen m_pen; QBrush m_brush; double m_dWidth; double m_dHeight; QRectF m_boundingRect; QGraphicsPathItem* m_pMovingCopy; //图元移动时的副本 QPointF m_movingIniPos; //移动副本开始移动初始点 QVector m_vecHanle; }; class GraphicsBaseItem : public QObject, public AbstractShapeType { Q_OBJECT public: GraphicsBaseItem(QGraphicsItem *parent); virtual ~GraphicsBaseItem(); virtual void createMovingCopy(); virtual void removeMovingCopy(); virtual void moveMovingCopy(const QPointF&); protected: virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange, const QVariant&); virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*); }; #endif