|
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include "item.h"
-
- #include <QListWidgetItem>
- #include <QMimeData>
- #include <QDrag>
- #include <QPainter>
- #include <QMouseEvent>
- #include <QDropEvent>
- #include <QGraphicsView>
- #include <QMessageBox>
-
- MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent)
- , ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
-
- /* 1. 场景 */
- m_scene = new QGraphicsScene(this);
- ui->graphicsView->setScene(m_scene);
- ui->graphicsView->setSceneRect(0, 0, 800, 600);
- ui->graphicsView->setDragMode(QGraphicsView::RubberBandDrag);
-
- /* 2. 列表 */
- ui->listWidget->setViewMode(QListView::IconMode);
- ui->listWidget->setIconSize(QSize(60, 30));
- ui->listWidget->setDragEnabled(false);
- ui->listWidget->viewport()->installEventFilter(this);
-
- /* 3. 填充列表 */
- createComponents();
- }
-
- MainWindow::~MainWindow()
- {
- delete ui;
- }
-
- /* ---------- 拖拽核心 ---------- */
- bool MainWindow::eventFilter(QObject *obj, QEvent *event)
- {
- if (obj == ui->listWidget->viewport()) {
- static QListWidgetItem *dragItem = nullptr;
- static QPoint startPos;
-
- if (event->type() == QEvent::MouseButtonPress) {
- auto *me = static_cast<QMouseEvent*>(event);
- if (me->button() == Qt::LeftButton) {
- dragItem = ui->listWidget->itemAt(me->pos());
- startPos = me->pos();
- }
- } else if (event->type() == QEvent::MouseMove && dragItem) {
- auto *me = static_cast<QMouseEvent*>(event);
- if ((me->pos() - startPos).manhattanLength()
- >= QApplication::startDragDistance()) {
-
- QString type = dragItem->data(Qt::UserRole).toString();
-
- QMimeData *mime = new QMimeData;
- mime->setData("application/x-component", type.toUtf8());
-
- QDrag *drag = new QDrag(this);
- drag->setMimeData(mime);
- drag->setPixmap(dragItem->icon().pixmap(ui->listWidget->iconSize()));
- drag->setHotSpot(drag->pixmap().rect().center());
- drag->exec(Qt::CopyAction);
-
- dragItem = nullptr;
- }
- } else if (event->type() == QEvent::MouseButtonRelease) {
- dragItem = nullptr;
- }
- }
- return QMainWindow::eventFilter(obj, event);
- }
-
- /* ---------- 填充列表 ---------- */
- void MainWindow::createComponents()
- {
- struct Comp { QString name; QColor color; };
- const QVector<Comp> comps = {
- {"常开", Qt::blue},
- {"常闭", Qt::red},
- {"比较", Qt::green},
- {"线圈", Qt::darkYellow}
- };
-
- for (const Comp &c : comps) {
- QListWidgetItem *it = new QListWidgetItem(c.name, ui->listWidget);
-
- QPixmap pix(60, 30);
- pix.fill(Qt::white);
- QPainter p(&pix);
- p.setRenderHint(QPainter::Antialiasing);
- p.setBrush(c.color.lighter(150));
- p.setPen(QPen(c.color, 2));
- p.drawRoundedRect(QRect(5, 5, 50, 20), 3, 3);
- p.setPen(Qt::black);
- p.drawText(QRect(5, 5, 50, 20), Qt::AlignCenter, c.name);
-
- it->setIcon(QIcon(pix));
- it->setData(Qt::UserRole, c.name);
- }
- }
-
- void MainWindow::on_listWidget_currentTextChanged(const QString &text)
- {
- selectedComponentType = text;
- }
-
- void MainWindow::on_pushButton_clicked()
- {
- // 1. 找场景中被选中的连线
- QList<QGraphicsItem*> selectedItems = ui->graphicsView->scene()->selectedItems();
- Connection* selectedConn = nullptr;
- for (QGraphicsItem* item : selectedItems) {
- selectedConn = dynamic_cast<Connection*>(item);
- if (selectedConn) break;
- }
- if (!selectedConn) {
- QMessageBox::warning(this, "提示", "请先选中一条连线");
- return;
- }
- if (selectedComponentType.isEmpty()) {
- QMessageBox::warning(this, "提示", "请先在列表中选择要插入的组件");
- return;
- }
-
- // 2. 计算插入点(中点)
- QLineF lf = selectedConn->line();
- QPointF insertPos = (lf.p1() + lf.p2()) / 2;
-
- // 3. 删除原连线
- Item* from = selectedConn->from_;
- Item* to = selectedConn->to_;
- Item::AnchorType fromType = selectedConn->fromType_;
- Item::AnchorType toType = selectedConn->toType_;
-
- from->removeConnection(selectedConn);
- to->removeConnection(selectedConn);
- ui->graphicsView->scene()->removeItem(selectedConn);
- delete selectedConn;
-
- // 4. 插入新元件
- Item* newItem = new Item(selectedComponentType);
- newItem->setPos(insertPos);
- connect(newItem, &Item::requestCopy, ui->graphicsView, &MyGraphicsView::onItemRequestCopy);
- connect(newItem, &Item::requestDelete, ui->graphicsView, &MyGraphicsView::onItemRequestDelete);
- ui->graphicsView->scene()->addItem(newItem);
-
- // 5. 新建两条连线
- Connection* c1 = new Connection(from, fromType, newItem, Item::Left);
- ui->graphicsView->scene()->addItem(c1);
- Connection* c2 = new Connection(newItem, Item::Right, to, toType);
- ui->graphicsView->scene()->addItem(c2);
- }
|