#include "item.h" #include "connection.h" #include "myscene.h" #include #include #include #include Item::Item(const QString &type, QGraphicsItem *parent) : QGraphicsObject(parent), type_(type), registerId_("") { setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges); } QRectF Item::boundingRect() const { return QRectF(-22, -12, 44, 32); } QPointF Item::anchorPos(AnchorType type) const { // 对于"按钮"和"指示灯"类型,返回无效坐标 if (type_ == "按钮" || type_ == "指示灯") { return QPointF(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } // 其他类型正常返回连接点位置 return mapToScene(type == Left ? QPointF(-18, 0) : QPointF(18, 0)); } void Item::addConnection(Connection* conn) { // 对于"按钮"和"指示灯"类型,不允许添加连接 if (type_ == "按钮" || type_ == "指示灯") { return; } if (!connections_.contains(conn)) { connections_.append(conn); } } void Item::removeConnection(Connection* conn) { connections_.removeAll(conn); } QList Item::connections() { return connections_; } QString Item::itemType() { return type_; } bool Item::setRegisterId(const QString &id) { if(registerId_.isEmpty()) { registerId_ = id; return true; } return false; } void Item::setRegisterValue(const QString ®isterId, quint16 value) { if (registerId_ == registerId) { registerValue_ = value; update(); // 触发重绘 } } QStringList Item::resetRegister() { QStringList unboundRegs; if (!registerId_.isEmpty()) { unboundRegs << registerId_; registerId_.clear(); registerValue_ = 0; update(); } return unboundRegs; } void Item::MenuActions(QMenu *menu) { menu->addAction("复制"); menu->addAction("删除"); menu->addAction("对象"); menu->addAction("重置"); } void Item::addMenuActions(QMenu *menu) { Q_UNUSED(menu); } void Item::handleMenuAction(QAction *action) { if (action->text() == "复制") { emit requestCopy(this); } if (action->text() == "删除") { emit requestDelete(this); } if (action->text() == "对象"){ emit requestBindRegister(this); } if (action->text() == "重置"){ emit requestReset(this); } } QVariant Item::itemChange(GraphicsItemChange change, const QVariant &value) { // if (change == QGraphicsItem::ItemPositionChange) { // for (Connection* conn : connections_) // conn->updatePosition(); // } // if (change == ItemPositionChange && scene()) { // // 获取场景(确保是 GridScene) // if (auto myScene = dynamic_cast(scene())) { // if (myScene->getSnapToGrid()) { // // 获取网格大小 // int gridSize = myScene->getGridSize(); // // 对齐到网格 // QPointF newPos = value.toPointF(); // qreal xV = qRound(newPos.x() / gridSize) * gridSize; // qreal yV = qRound(newPos.y() / gridSize) * gridSize; // return QPointF(xV, yV); // } // } // } // 处理位置即将改变事件(网格对齐) if (change == ItemPositionChange && scene()) { QPointF newPos = value.toPointF(); // 检查是否启用网格对齐 if (auto myScene = dynamic_cast(scene())) { if (myScene->getSnapToGrid()) { int gridSize = myScene->getGridSize(); // 计算对齐位置 qreal xV = qRound(newPos.x() / gridSize) * gridSize; qreal yV = qRound(newPos.y() / gridSize) * gridSize; // 返回对齐后的位置 return QPointF(xV, yV); } } } // 处理位置已改变事件(更新连线) else if (change == QGraphicsItem::ItemPositionHasChanged) { // 使用范围for循环安全遍历(防止在更新过程中连接被修改) QList connectionsCopy = connections_; for (Connection* conn : connectionsCopy) { if (connections_.contains(conn)) { // 确保连接仍然存在 conn->updatePosition(); } } } return QGraphicsObject::itemChange(change, value); } void Item::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { QMenu menu; // 创建菜单 MenuActions(&menu); addMenuActions(&menu); // 执行菜单 QAction *selected = menu.exec(event->screenPos()); // 处理菜单动作 if (selected) { handleMenuAction(selected); } }