您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

159 行
5.1 KiB

  1. #include "plc.h"
  2. #include "ui_plc.h"
  3. #include "item.h"
  4. #include <QListWidgetItem>
  5. #include <QMimeData>
  6. #include <QDrag>
  7. #include <QPainter>
  8. #include <QMouseEvent>
  9. #include <QDropEvent>
  10. #include <QGraphicsView>
  11. #include <QMessageBox>
  12. #include "creatitem.h"
  13. PLC::PLC(QWidget *parent) :
  14. QWidget(parent),
  15. ui(new Ui::PLC)
  16. {
  17. ui->setupUi(this);
  18. /* 1. 场景 */
  19. m_scene = new QGraphicsScene(this);
  20. ui->graphicsView->setScene(m_scene);
  21. ui->graphicsView->setSceneRect(0, 0, 800, 600);
  22. ui->graphicsView->setDragMode(QGraphicsView::RubberBandDrag);
  23. /* 2. 列表 */
  24. ui->listWidget->setViewMode(QListView::IconMode);
  25. ui->listWidget->setIconSize(QSize(60, 30));
  26. ui->listWidget->setDragEnabled(false);
  27. ui->listWidget->viewport()->installEventFilter(this);
  28. /* 3. 填充列表 */
  29. createComponents();
  30. connect(ui->listWidget,&QListWidget::currentTextChanged,this,&PLC::onListwidgetCurrenttextchanged);
  31. connect(ui->btn_insert,&QPushButton::clicked,this,&PLC::btnInsertClicked);
  32. }
  33. PLC::~PLC()
  34. {
  35. delete ui;
  36. }
  37. bool PLC::eventFilter(QObject *obj, QEvent *event)
  38. {
  39. if (obj == ui->listWidget->viewport()) {
  40. static QListWidgetItem *dragItem = nullptr;
  41. static QPoint startPos;
  42. if (event->type() == QEvent::MouseButtonPress) {
  43. auto *me = static_cast<QMouseEvent*>(event);
  44. if (me->button() == Qt::LeftButton) {
  45. dragItem = ui->listWidget->itemAt(me->pos());
  46. startPos = me->pos();
  47. }
  48. } else if (event->type() == QEvent::MouseMove && dragItem) {
  49. auto *me = static_cast<QMouseEvent*>(event);
  50. if ((me->pos() - startPos).manhattanLength()
  51. >= QApplication::startDragDistance()) {
  52. QString type = dragItem->data(Qt::UserRole).toString();
  53. QMimeData *mime = new QMimeData;
  54. mime->setData("application/x-component", type.toUtf8());
  55. QDrag *drag = new QDrag(this);
  56. drag->setMimeData(mime);
  57. drag->setPixmap(dragItem->icon().pixmap(ui->listWidget->iconSize()));
  58. drag->setHotSpot(drag->pixmap().rect().center());
  59. drag->exec(Qt::CopyAction);
  60. dragItem = nullptr;
  61. }
  62. } else if (event->type() == QEvent::MouseButtonRelease) {
  63. dragItem = nullptr;
  64. }
  65. }
  66. return QWidget::eventFilter(obj, event);
  67. }
  68. void PLC::createComponents()
  69. {
  70. struct Comp { QString name; QColor color; };
  71. const QVector<Comp> comps = {
  72. {"常开", Qt::blue},
  73. {"常闭", Qt::red},
  74. {"比较", Qt::green},
  75. {"线圈", Qt::darkYellow}
  76. };
  77. for (const Comp &c : comps) {
  78. QListWidgetItem *it = new QListWidgetItem(c.name, ui->listWidget);
  79. QPixmap pix(60, 30);
  80. pix.fill(Qt::white);
  81. QPainter p(&pix);
  82. p.setRenderHint(QPainter::Antialiasing);
  83. p.setBrush(c.color.lighter(150));
  84. p.setPen(QPen(c.color, 2));
  85. p.drawRoundedRect(QRect(5, 5, 50, 20), 3, 3);
  86. p.setPen(Qt::black);
  87. p.drawText(QRect(5, 5, 50, 20), Qt::AlignCenter, c.name);
  88. it->setIcon(QIcon(pix));
  89. it->setData(Qt::UserRole, c.name);
  90. }
  91. }
  92. void PLC::onListwidgetCurrenttextchanged(const QString &text)
  93. {
  94. selectedComponentType = text;
  95. }
  96. void PLC::btnInsertClicked()
  97. {
  98. // 1. 找场景中被选中的连线
  99. QList<QGraphicsItem*> selectedItems = ui->graphicsView->scene()->selectedItems();
  100. Connection* selectedConn = nullptr;
  101. for (QGraphicsItem* item : selectedItems) {
  102. selectedConn = dynamic_cast<Connection*>(item);
  103. if (selectedConn) break;
  104. }
  105. if (!selectedConn) {
  106. QMessageBox::warning(this, "提示", "请先选中一条连线");
  107. return;
  108. }
  109. if (selectedComponentType.isEmpty()) {
  110. QMessageBox::warning(this, "提示", "请先在列表中选择要插入的组件");
  111. return;
  112. }
  113. // 2. 计算插入点(中点)
  114. QLineF lf = selectedConn->line();
  115. QPointF insertPos = (lf.p1() + lf.p2()) / 2;
  116. // 3. 删除原连线
  117. Item* from = selectedConn->from_;
  118. Item* to = selectedConn->to_;
  119. Item::AnchorType fromType = selectedConn->fromType_;
  120. Item::AnchorType toType = selectedConn->toType_;
  121. from->removeConnection(selectedConn);
  122. to->removeConnection(selectedConn);
  123. ui->graphicsView->scene()->removeItem(selectedConn);
  124. delete selectedConn;
  125. // 4. 插入新元件
  126. Item* newItem = creatItem(selectedComponentType);
  127. newItem->setPos(insertPos);
  128. connect(newItem, &Item::requestCopy, ui->graphicsView, &MyGraphicsView::onItemRequestCopy);
  129. connect(newItem, &Item::requestDelete, ui->graphicsView, &MyGraphicsView::onItemRequestDelete);
  130. ui->graphicsView->scene()->addItem(newItem);
  131. // 5. 新建两条连线
  132. Connection* c1 = new Connection(from, fromType, newItem, Item::Left);
  133. ui->graphicsView->scene()->addItem(c1);
  134. Connection* c2 = new Connection(newItem, Item::Right, to, toType);
  135. ui->graphicsView->scene()->addItem(c2);
  136. }