#include "mygraphicsview.h" #include #include #include #include MyGraphicsView::MyGraphicsView(QWidget *parent) : QGraphicsView(parent) { setAcceptDrops(true); viewport()->setAcceptDrops(true); setRenderHint(QPainter::Antialiasing); setFocusPolicy(Qt::StrongFocus); } void MyGraphicsView::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasFormat("application/x-component")) event->acceptProposedAction(); else event->ignore(); } void MyGraphicsView::dragMoveEvent(QDragMoveEvent *event) { if (event->mimeData()->hasFormat("application/x-component")) event->acceptProposedAction(); else event->ignore(); } void MyGraphicsView::dropEvent(QDropEvent *event) { if (!event->mimeData()->hasFormat("application/x-component")) { event->ignore(); return; } QString type = QString::fromUtf8(event->mimeData()->data("application/x-component")); QPointF scenePos = mapToScene(event->pos()); Item *item = new Item(type); item->setPos(scenePos); if (scene()) scene()->addItem(item); event->acceptProposedAction(); } void MyGraphicsView::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Delete && scene()) { QList selectedItems = scene()->selectedItems(); for (QGraphicsItem* item : selectedItems) { // 如果是Item,顺便删除其连线 if (auto node = dynamic_cast(item)) { QList conns = node->connections(); for (Connection* conn : conns) { scene()->removeItem(conn); conn->from_->removeConnection(conn); conn->to_->removeConnection(conn); delete conn; } } scene()->removeItem(item); delete item; } } else { QGraphicsView::keyPressEvent(event); } } // ----------- 连线交互 ------------ Item* MyGraphicsView::anchorItemAt(const QPoint& viewPos, Item::AnchorType& anchorType) { QPointF scenePos = mapToScene(viewPos); for (QGraphicsItem* item : scene()->items(scenePos)) { if (Item* node = dynamic_cast(item)) { QRectF r = node->boundingRect(); QPointF local = node->mapFromScene(scenePos); if (QLineF(local, QPointF(r.left(), r.center().y())).length() < 10) { anchorType = Item::Left; return node; } if (QLineF(local, QPointF(r.right(), r.center().y())).length() < 10) { anchorType = Item::Right; return node; } } } return nullptr; } void MyGraphicsView::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { Item::AnchorType anchor; Item* node = anchorItemAt(event->pos(), anchor); if (node) { drawingConnection_ = true; startItem_ = node; startAnchor_ = anchor; tempLine_ = scene()->addLine(QLineF(node->anchorPos(anchor), mapToScene(event->pos())), QPen(Qt::darkGray, 2, Qt::DashLine)); return; } } QGraphicsView::mousePressEvent(event); } void MyGraphicsView::mouseMoveEvent(QMouseEvent *event) { if (drawingConnection_ && tempLine_) { QLineF l = tempLine_->line(); l.setP2(mapToScene(event->pos())); tempLine_->setLine(l); return; } QGraphicsView::mouseMoveEvent(event); } void MyGraphicsView::mouseReleaseEvent(QMouseEvent *event) { if (drawingConnection_ && tempLine_) { // 检查鼠标释放点是否在某个Item boundingRect内 QPointF scenePos = mapToScene(event->pos()); for (QGraphicsItem* item : scene()->items(scenePos)) { if (Item* node = dynamic_cast(item)) { QRectF r = node->boundingRect(); QPointF local = node->mapFromScene(scenePos); // 计算落点距离左右端点 double distLeft = QLineF(local, QPointF(r.left(), r.center().y())).length(); double distRight = QLineF(local, QPointF(r.right(), r.center().y())).length(); Item::AnchorType anchor = (distLeft < distRight) ? Item::Left : Item::Right; // 生成连线 Connection* conn = new Connection(startItem_, startAnchor_, node, anchor); scene()->addItem(conn); break; } } // 清除临时线 scene()->removeItem(tempLine_); delete tempLine_; tempLine_ = nullptr; drawingConnection_ = false; startItem_ = nullptr; return; } QGraphicsView::mouseReleaseEvent(event); }