|
- #include "mygraphicsview.h"
- #include <QMimeData>
- #include <QCursor>
- #include <QGraphicsScene>
- #include <QDebug>
-
- 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<QGraphicsItem*> selectedItems = scene()->selectedItems();
- for (QGraphicsItem* item : selectedItems) {
- // 如果是Item,顺便删除其连线
- if (auto node = dynamic_cast<Item*>(item)) {
- QList<Connection*> 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*>(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*>(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);
- }
|