#ifndef GRAPHICSITEMS_H #define GRAPHICSITEMS_H #include #include #include #include #include #include #include #include #include // 命名项接口(用于属性设置) class NamedItem { public: virtual QString name() const = 0; virtual void setName(const QString &name) = 0; virtual ~NamedItem() = default; }; // 可调整大小的图形基类(模板) template class ResizableShape : public BaseShape, public NamedItem { protected: bool m_resizing; QString m_name; QPointF m_initialPos; // 用于存储调整开始时的位置 // 获取右下角调整区域 QRectF getResizeArea() const { QRectF r = this->rect(); return QRectF(r.bottomRight() - QPointF(20, 20), r.bottomRight()); } // 检测是否在右下角调整区域 bool isInResizeArea(const QPointF &pos) const { return getResizeArea().contains(pos); } public: ResizableShape(qreal x, qreal y, qreal w, qreal h) : BaseShape(x, y, w, h), m_resizing(false) { this->setFlag(QGraphicsItem::ItemIsMovable, true); this->setFlag(QGraphicsItem::ItemIsSelectable, true); this->setAcceptHoverEvents(true); this->setCursor(Qt::SizeAllCursor); // 默认光标为移动光标 } // 事件处理(调整大小逻辑) void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override { if (isInResizeArea(event->pos())) { this->setCursor(Qt::SizeFDiagCursor); // 右下角显示缩放光标 } else { this->setCursor(Qt::SizeAllCursor); // 其他区域显示移动光标 } BaseShape::hoverMoveEvent(event); } void mousePressEvent(QGraphicsSceneMouseEvent *event) override { if (isInResizeArea(event->pos())) { m_resizing = true; m_initialPos = event->pos(); // 存储初始位置 this->setCursor(Qt::SizeFDiagCursor); } else { m_resizing = false; BaseShape::mousePressEvent(event); } } void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override { if (m_resizing) { // 计算尺寸变化量 QPointF delta = event->pos() - m_initialPos; QRectF newRect = this->rect(); // 保持左上角不变,调整右下角 newRect.setWidth(newRect.width() + delta.x()); newRect.setHeight(newRect.height() + delta.y()); // 设置最小尺寸 if (newRect.width() < 20) newRect.setWidth(20); if (newRect.height() < 20) newRect.setHeight(20); this->setRect(newRect); this->update(); m_initialPos = event->pos(); // 更新初始位置 } else { BaseShape::mouseMoveEvent(event); } } void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override { if (m_resizing) { m_resizing = false; // 根据位置恢复光标 if (isInResizeArea(event->pos())) { this->setCursor(Qt::SizeFDiagCursor); // 仍在调整区域 } else { this->setCursor(Qt::SizeAllCursor); // 离开调整区域 } } BaseShape::mouseReleaseEvent(event); } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override { BaseShape::paint(painter, option, widget); } // 命名项接口实现 QString name() const override { return m_name; } void setName(const QString &name) override { m_name = name; } }; // 可调整大小的矩形(按钮) class ResizableRectangle : public ResizableShape { public: ResizableRectangle(qreal x, qreal y, qreal w, qreal h) : ResizableShape(x, y, w, h) { m_pressedColor = Qt::darkYellow; m_releasedColor = Qt::yellow; this->setBrush(m_releasedColor); } QColor pressedColor() const { return m_pressedColor; } void setPressedColor(const QColor &color) { m_pressedColor = color; } QColor releasedColor() const { return m_releasedColor; } void setReleasedColor(const QColor &color) { m_releasedColor = color; this->setBrush(m_releasedColor); // 更新显示 } private: QColor m_pressedColor; // 按下颜色 QColor m_releasedColor; // 释放颜色 }; // 可调整大小的椭圆(指示灯) class ResizableEllipse : public ResizableShape { public: ResizableEllipse(qreal x, qreal y, qreal w, qreal h) : ResizableShape(x, y, w, h) { m_onColor = Qt::green; m_offColor = Qt::red; this->setBrush(m_offColor); } QColor onColor() const { return m_onColor; } void setOnColor(const QColor &color) { m_onColor = color; this->setBrush(m_onColor); // 更新显示 } QColor offColor() const { return m_offColor; } void setOffColor(const QColor &color) { m_offColor = color; } private: QColor m_onColor; // 开状态颜色 QColor m_offColor; // 关状态颜色 }; #endif // GRAPHICSITEMS_H