You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

646 regels
23 KiB

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.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 <QAction>
  13. #include <QFileDialog>
  14. #include "creatitem.h"
  15. MainWindow::MainWindow(QWidget *parent)
  16. : QMainWindow(parent)
  17. , ui(new Ui::MainWindow)
  18. , registerManager(new RegisterManager(this))
  19. , modbusManager(new ModbusManager(registerManager, this))
  20. {
  21. ui->setupUi(this);
  22. // 初始化PLC标签页
  23. ui->plc_tab_widget->setTabsClosable(true);
  24. ui->plc_tab_widget->setMovable(true);
  25. // 初始化HMI标签页
  26. ui->hmi_tab_widget->setTabsClosable(true);
  27. ui->hmi_tab_widget->setMovable(true);
  28. /* 2. 列表 */
  29. ui->listWidget->setViewMode(QListView::IconMode);
  30. ui->listWidget->setIconSize(QSize(60, 30));
  31. ui->listWidget->setDragEnabled(false);
  32. ui->listWidget->viewport()->installEventFilter(this);
  33. newPage(true);
  34. newPage(false);
  35. createComponents();
  36. connect(ui->plc_tab_widget, &QTabWidget::tabCloseRequested, this, &MainWindow::onTabCloseRequested);
  37. connect(ui->hmi_tab_widget, &QTabWidget::tabCloseRequested, this, &MainWindow::onTabCloseRequested);
  38. connect(ui->listWidget,&QListWidget::currentTextChanged,this,&MainWindow::onListwidgetCurrenttextchanged);
  39. connect(ui->action_plc,&QAction::triggered,this,&MainWindow::plcChange);
  40. connect(ui->action_hmi,&QAction::triggered,this,&MainWindow::hmiChange);
  41. connect(ui->action_new, &QAction::triggered, this, &MainWindow::newProject);
  42. connect(ui->action_save, &QAction::triggered, this, &MainWindow::saveProject);
  43. connect(ui->action_open, &QAction::triggered, this, &MainWindow::openProject);
  44. connect(ui->action_connect, &QAction::triggered, this, &MainWindow::connection);
  45. connect(ui->action_disconnect, &QAction::triggered, this, &MainWindow::disconnection);
  46. connect(ui->btn_insert, &QPushButton::clicked, this, &MainWindow::btnInsertClicked);
  47. connect(modbusManager, &ModbusManager::connectionStatusChanged,
  48. this, &MainWindow::updateConnectionStatus);
  49. // connect(modbusManager, &ModbusManager::connectionStatusChanged,
  50. // this, &PLC::updateConnectionStatus);
  51. // connect(modbusManager, &ModbusManager::errorOccurred,
  52. // this, &PLC::handleModbusError);
  53. ui->stackedWidget->setCurrentIndex(0);
  54. setWindowTitle("PLC编辑器");
  55. }
  56. MainWindow::~MainWindow()
  57. {
  58. qDeleteAll(plcScenes);
  59. qDeleteAll(plcViews);
  60. qDeleteAll(hmiScenes);
  61. qDeleteAll(hmiViews);
  62. delete ui;
  63. }
  64. void MainWindow::newPage(bool isPlc)
  65. {
  66. if (isPlc) {
  67. // 创建新场景
  68. MyScene* newScene = new MyScene(this);
  69. // 设置网格属性
  70. newScene->setGridSize(20); // 20像素网格
  71. newScene->setGridColor(QColor(200, 200, 200, 150)); // 半透明灰色
  72. newScene->setSnapToGrid(true); // 启用对齐网格
  73. // 创建新视图
  74. MyGraphicsView* newView = new MyGraphicsView(this);
  75. newView->setScene(newScene);
  76. newView->setSceneRect(0, 0, 800, 600);
  77. newView->setDragMode(QGraphicsView::RubberBandDrag);
  78. // 添加到PLC标签页
  79. int newIndex = ui->plc_tab_widget->addTab(newView, QString("页面 %1").arg(plcScenes.size() + 1));
  80. plcPageTitles.append(""); // 初始化为空字符串
  81. ui->plc_tab_widget->setCurrentIndex(newIndex);
  82. // 保存场景和视图
  83. plcScenes.append(newScene);
  84. plcViews.append(newView);
  85. connect(newView, &MyGraphicsView::itemBoundToRegister,
  86. registerManager, &RegisterManager::bindItem);
  87. connect(newView, &MyGraphicsView::itemResetRegister,
  88. registerManager, &RegisterManager::unbindItem);
  89. } else {
  90. // 创建新场景
  91. QGraphicsScene* newScene = new QGraphicsScene(this);
  92. // 创建新视图
  93. MyGraphicsView* newView = new MyGraphicsView(this);
  94. newView->setScene(newScene);
  95. newView->setSceneRect(0, 0, 800, 600);
  96. newView->setDragMode(QGraphicsView::RubberBandDrag);
  97. // 添加到HMI标签页
  98. int newIndex = ui->hmi_tab_widget->addTab(newView, QString("页面 %1").arg(hmiScenes.size() + 1));
  99. hmiPageTitles.append(""); // 初始化为空字符串
  100. ui->hmi_tab_widget->setCurrentIndex(newIndex);
  101. // 保存场景和视图
  102. hmiScenes.append(newScene);
  103. hmiViews.append(newView);
  104. connect(newView, &MyGraphicsView::itemBoundToRegister,
  105. registerManager, &RegisterManager::bindItem);
  106. connect(newView, &MyGraphicsView::itemResetRegister,
  107. registerManager, &RegisterManager::unbindItem);
  108. connect(newView, &MyGraphicsView::itemSetON,
  109. modbusManager, &ModbusManager::writeRegister);
  110. }
  111. }
  112. void MainWindow::createComponents()
  113. {
  114. ui->listWidget->clear();
  115. if (currentIsPLC_)
  116. {
  117. struct Comp { QString name; QColor color; };
  118. const QVector<Comp> comps = {
  119. {"常开", Qt::blue},
  120. {"常闭", Qt::red},
  121. {"比较", Qt::green},
  122. {"线圈", Qt::darkYellow}
  123. };
  124. for (const Comp &c : comps) {
  125. QListWidgetItem *it = new QListWidgetItem(c.name, ui->listWidget);
  126. QPixmap pix(60, 30);
  127. pix.fill(Qt::white);
  128. QPainter p(&pix);
  129. p.setRenderHint(QPainter::Antialiasing);
  130. p.setBrush(c.color.lighter(150));
  131. p.setPen(QPen(c.color, 2));
  132. p.drawRoundedRect(QRect(5, 5, 50, 20), 3, 3);
  133. p.setPen(Qt::black);
  134. p.drawText(QRect(5, 5, 50, 20), Qt::AlignCenter, c.name);
  135. it->setIcon(QIcon(pix));
  136. it->setData(Qt::UserRole, c.name);
  137. }
  138. }
  139. else
  140. {
  141. struct Comp { QString name; QColor color; };
  142. const QVector<Comp> comps = {
  143. {"按钮", Qt::blue},
  144. {"指示灯", Qt::red}
  145. };
  146. for (const Comp &c : comps) {
  147. QListWidgetItem *it = new QListWidgetItem(c.name, ui->listWidget);
  148. QPixmap pix(60, 30);
  149. pix.fill(Qt::white);
  150. QPainter p(&pix);
  151. p.setRenderHint(QPainter::Antialiasing);
  152. p.setBrush(c.color.lighter(150));
  153. p.setPen(QPen(c.color, 2));
  154. p.drawRoundedRect(QRect(5, 5, 50, 20), 3, 3);
  155. p.setPen(Qt::black);
  156. p.drawText(QRect(5, 5, 50, 20), Qt::AlignCenter, c.name);
  157. it->setIcon(QIcon(pix));
  158. it->setData(Qt::UserRole, c.name);
  159. }
  160. }
  161. }
  162. void MainWindow::clearScene()
  163. {
  164. if(currentIsPLC_)
  165. {
  166. if (currentPageIndex() >= 0 && currentPageIndex() < plcScenes.size()) {
  167. plcScenes[currentPageIndex()]->clear();
  168. }
  169. }
  170. else
  171. {
  172. if (currentPageIndex() >= 0 && currentPageIndex() < hmiScenes.size()) {
  173. hmiScenes[currentPageIndex()]->clear();
  174. }
  175. }
  176. }
  177. void MainWindow::applyProjectToScene(const Project &proj, int pageIndex)
  178. {
  179. if (currentIsPLC_)
  180. {
  181. if (pageIndex < 0 || pageIndex >= plcScenes.size())
  182. return;
  183. plcScenes[pageIndex]->clear();
  184. QVector<Item*> itemObjs;
  185. for (const auto& d : proj.items_) {
  186. Item* item = creatItem(d.type);
  187. if (!item) continue;
  188. item->setPos(d.x, d.y);
  189. item->setRegisterId(d.registerId);
  190. if (d.type == "比较") {
  191. Comparator* compare = dynamic_cast<Comparator*>(item);
  192. if (compare) {
  193. compare->setRegisterId(d.registerId2);
  194. compare->setCompare(d.compare);
  195. if (d.registerId.left(1) == "K")
  196. {
  197. compare->setRegisterValue(d.registerId, d.registerId.mid(1).toInt());
  198. } else {
  199. registerManager->bindItem(compare, d.registerId);
  200. }
  201. if (d.registerId2.left(1) == "K")
  202. {
  203. compare->setRegisterValue(d.registerId2, d.registerId2.mid(1).toInt());
  204. } else {
  205. registerManager->bindItem(compare, d.registerId2);
  206. }
  207. }
  208. }
  209. connect(item, &Item::requestCopy, plcViews[pageIndex], &MyGraphicsView::onItemRequestCopy);
  210. connect(item, &Item::requestDelete, plcViews[pageIndex], &MyGraphicsView::onItemRequestDelete);
  211. connect(item, &Item::requestBindRegister, plcViews[pageIndex], &MyGraphicsView::onItemRequestBindRegister);
  212. connect(item, &Item::requestCompare, plcViews[pageIndex], &MyGraphicsView::onItemRequestCompare);
  213. connect(item, &Item::requestReset, plcViews[pageIndex], &MyGraphicsView::onItemRequestReset);
  214. connect(item, &Item::requestSetON,plcViews[pageIndex], &MyGraphicsView::onItemRequestSetON);
  215. plcScenes[pageIndex]->addItem(item);
  216. if (d.type != "比较")
  217. {
  218. registerManager->bindItem(item,d.registerId);
  219. }
  220. itemObjs.append(item);
  221. }
  222. for (const auto& c : proj.connections_) {
  223. if (c.from >= 0 && c.from < itemObjs.size() && c.to >= 0 && c.to < itemObjs.size()) {
  224. Connection* conn = new Connection(
  225. itemObjs[c.from], static_cast<Item::AnchorType>(c.fromType),
  226. itemObjs[c.to], static_cast<Item::AnchorType>(c.toType));
  227. plcScenes[pageIndex]->addItem(conn);
  228. }
  229. }
  230. }
  231. else
  232. {
  233. if (pageIndex < 0 || pageIndex >= hmiScenes.size())
  234. return;
  235. hmiScenes[pageIndex]->clear();
  236. QVector<Item*> itemObjs;
  237. for (const auto& d : proj.items_) {
  238. Item* item = creatItem(d.type);
  239. if (!item) continue;
  240. item->setPos(d.x, d.y);
  241. item->setRegisterId(d.registerId);
  242. if (d.type == "按钮") {
  243. Button* button = dynamic_cast<Button*>(item);
  244. if (button) {
  245. button->setCustomImage(d.imagePath);
  246. button->setCurrentSize(d.size);
  247. }
  248. } else if (d.type == "指示灯") {
  249. Light* light = dynamic_cast<Light*>(item);
  250. if (light) {
  251. light->setOnImage(d.onImagePath);
  252. light->setOffImage(d.offImagePath);
  253. light->setCurrentSize(d.size);
  254. }
  255. }
  256. connect(item, &Item::requestCopy, hmiViews[pageIndex], &MyGraphicsView::onItemRequestCopy);
  257. connect(item, &Item::requestDelete, hmiViews[pageIndex], &MyGraphicsView::onItemRequestDelete);
  258. connect(item, &Item::requestBindRegister, hmiViews[pageIndex], &MyGraphicsView::onItemRequestBindRegister);
  259. connect(item, &Item::requestCompare, hmiViews[pageIndex], &MyGraphicsView::onItemRequestCompare);
  260. connect(item, &Item::requestReset, hmiViews[pageIndex], &MyGraphicsView::onItemRequestReset);
  261. connect(item, &Item::requestSetON,hmiViews[pageIndex], &MyGraphicsView::onItemRequestSetON);
  262. hmiScenes[pageIndex]->addItem(item);
  263. registerManager->bindItem(item,d.registerId);
  264. itemObjs.append(item);
  265. }
  266. }
  267. }
  268. void MainWindow::extractSceneToProject(Project &proj, int pageIndex)
  269. {
  270. if (currentIsPLC_)
  271. {
  272. if (pageIndex < 0 || pageIndex >= plcScenes.size()) return;
  273. proj.clear();
  274. QList<Item*> items;
  275. for (QGraphicsItem* gi : plcScenes[pageIndex]->items()){
  276. if (Item* it = dynamic_cast<Item*>(gi)){
  277. items.append(it);
  278. }
  279. }
  280. for (Item* it : items) {
  281. Project::ItemData d;
  282. d.type = it->itemType();
  283. d.x = it->pos().x();
  284. d.y = it->pos().y();
  285. d.registerId = it->registerId();
  286. if (d.type == "比较") {
  287. Comparator* compare = dynamic_cast<Comparator*>(it);
  288. if (compare) {
  289. d.registerId2 = compare->registerId2();
  290. d.compare = compare->compare();
  291. }
  292. }
  293. proj.items_.append(d);
  294. }
  295. for (QGraphicsItem* gi : plcScenes[pageIndex]->items()) {
  296. if (Connection* conn = dynamic_cast<Connection*>(gi)) {
  297. int fromIdx = items.indexOf(conn->from_);
  298. int toIdx = items.indexOf(conn->to_);
  299. if (fromIdx >= 0 && toIdx >= 0) {
  300. Project::ConnectionData c;
  301. c.from = fromIdx;
  302. c.to = toIdx;
  303. c.fromType = static_cast<int>(conn->fromType_);
  304. c.toType = static_cast<int>(conn->toType_);
  305. proj.connections_.append(c);
  306. }
  307. }
  308. }
  309. }
  310. else
  311. {
  312. if (pageIndex < 0 || pageIndex >= hmiScenes.size()) return;
  313. proj.clear();
  314. QList<Item*> items;
  315. for (QGraphicsItem* gi : hmiScenes[pageIndex]->items()){
  316. if (Item* it = dynamic_cast<Item*>(gi)){
  317. items.append(it);
  318. }
  319. }
  320. for (Item* it : items) {
  321. Project::ItemData d;
  322. d.type = it->itemType();
  323. d.x = it->pos().x();
  324. d.y = it->pos().y();
  325. d.registerId = it->registerId();
  326. if (d.type == "按钮") {
  327. Button* button = dynamic_cast<Button*>(it);
  328. if (button) {
  329. d.imagePath = button->imagePath();
  330. d.size = button->currentSize();
  331. }
  332. } else if (d.type == "指示灯") {
  333. Light* light = dynamic_cast<Light*>(it);
  334. if (light) {
  335. d.onImagePath = light->onImagePath();
  336. d.offImagePath = light->offImagePath();
  337. d.size = light->currentSize();
  338. }
  339. }
  340. proj.items_.append(d);
  341. }
  342. }
  343. }
  344. int MainWindow::currentPageIndex() const
  345. {
  346. if (currentIsPLC_) {
  347. return ui->plc_tab_widget->currentIndex();
  348. } else {
  349. return ui->hmi_tab_widget->currentIndex();
  350. }
  351. }
  352. bool MainWindow::eventFilter(QObject *obj, QEvent *event)
  353. {
  354. if (obj == ui->listWidget->viewport()) {
  355. static QListWidgetItem *dragItem = nullptr;
  356. static QPoint startPos;
  357. if (event->type() == QEvent::MouseButtonPress) {
  358. auto *me = static_cast<QMouseEvent*>(event);
  359. if (me->button() == Qt::LeftButton) {
  360. dragItem = ui->listWidget->itemAt(me->pos());
  361. startPos = me->pos();
  362. }
  363. } else if (event->type() == QEvent::MouseMove && dragItem) {
  364. auto *me = static_cast<QMouseEvent*>(event);
  365. if ((me->pos() - startPos).manhattanLength()
  366. >= QApplication::startDragDistance()) {
  367. QString type = dragItem->data(Qt::UserRole).toString();
  368. QMimeData *mime = new QMimeData;
  369. mime->setData("application/x-component", type.toUtf8());
  370. QDrag *drag = new QDrag(this);
  371. drag->setMimeData(mime);
  372. drag->setPixmap(dragItem->icon().pixmap(ui->listWidget->iconSize()));
  373. drag->setHotSpot(drag->pixmap().rect().center());
  374. drag->exec(Qt::CopyAction);
  375. dragItem = nullptr;
  376. }
  377. } else if (event->type() == QEvent::MouseButtonRelease) {
  378. dragItem = nullptr;
  379. }
  380. }
  381. return QWidget::eventFilter(obj, event);
  382. }
  383. void MainWindow::plcChange()
  384. {
  385. currentIsPLC_ = true;
  386. createComponents();
  387. ui->stackedWidget->setCurrentIndex(0); // 显示PLC页面
  388. setWindowTitle("PLC编辑器");
  389. }
  390. void MainWindow::hmiChange()
  391. {
  392. currentIsPLC_ = false;
  393. createComponents();
  394. ui->stackedWidget->setCurrentIndex(1); // 显示HMI页面
  395. setWindowTitle("HMI编辑器");
  396. }
  397. void MainWindow::newProject()
  398. {
  399. // // 检查当前tabwidget是否只有一个页面且页面内容为空
  400. // if (currentIsPLC_ && plcScenes.size() == 1 && plcScenes[0]->items().isEmpty()) {
  401. // // 复用第一个页面
  402. // clearScene();
  403. // setWindowTitle("PLC编辑器");
  404. // return;
  405. // }
  406. // if (!currentIsPLC_ && hmiScenes.size() == 1 && hmiScenes[0]->items().isEmpty()) {
  407. // clearScene();
  408. // setWindowTitle("HMI编辑器");
  409. // return;
  410. // }
  411. newPage(currentIsPLC_);
  412. // 更新窗口标题
  413. if (currentIsPLC_) {
  414. setWindowTitle("PLC编辑器");
  415. } else {
  416. setWindowTitle("HMI编辑器");
  417. }
  418. }
  419. void MainWindow::openProject()
  420. {
  421. QString filePath;
  422. QString filter;
  423. if (currentIsPLC_) {
  424. filter = "PLC项目文件 (*.plcproj)";
  425. filePath = QFileDialog::getOpenFileName(this, "打开PLC项目", "", filter);
  426. } else {
  427. filter = "HMI项目文件 (*.hmiproj)";
  428. filePath = QFileDialog::getOpenFileName(this, "打开HMI项目", "", filter);
  429. }
  430. if (filePath.isEmpty()) return;
  431. Project project;
  432. if (project.loadFromFile(filePath)) {
  433. // // 在当前模块新建一个页面
  434. // newPage(currentIsPLC_);
  435. // int newPageIndex = currentPageIndex();
  436. int newPageIndex = -1;
  437. if (currentIsPLC_ && plcScenes.size() == 1 && plcScenes[0]->items().isEmpty()) {
  438. newPageIndex = 0;
  439. } else if (!currentIsPLC_ && hmiScenes.size() == 1 && hmiScenes[0]->items().isEmpty()) {
  440. newPageIndex = 0;
  441. } else {
  442. newPage(currentIsPLC_);
  443. newPageIndex = currentPageIndex();
  444. }
  445. // 将项目应用到新页面
  446. applyProjectToScene(project, newPageIndex);
  447. // 设置标签页标题为文件名
  448. QString fileName = QFileInfo(filePath).fileName();
  449. if (currentIsPLC_) {
  450. plcPageTitles[newPageIndex] = fileName;
  451. ui->plc_tab_widget->setTabText(newPageIndex, fileName);
  452. } else {
  453. hmiPageTitles[newPageIndex] = fileName;
  454. ui->hmi_tab_widget->setTabText(newPageIndex, fileName);
  455. }
  456. } else {
  457. QMessageBox::critical(this, "错误", "无法打开项目文件");
  458. }
  459. }
  460. void MainWindow::saveProject()
  461. {
  462. QString filePath;
  463. QString filter;
  464. QString defaultSuffix;
  465. if (currentIsPLC_) {
  466. filter = "PLC项目文件 (*.plcproj)";
  467. defaultSuffix = "plcproj";
  468. filePath = QFileDialog::getSaveFileName(this, "保存PLC项目", "", filter);
  469. } else {
  470. filter = "HMI项目文件 (*.hmiproj)";
  471. defaultSuffix = "hmiproj";
  472. filePath = QFileDialog::getSaveFileName(this, "保存HMI项目", "", filter);
  473. }
  474. if (filePath.isEmpty()) return;
  475. // 确保文件有正确的扩展名
  476. if (!filePath.endsWith("." + defaultSuffix, Qt::CaseInsensitive)) {
  477. filePath += "." + defaultSuffix;
  478. }
  479. Project project;
  480. // 从当前页面提取项目
  481. extractSceneToProject(project, currentPageIndex());
  482. if (project.saveToFile(filePath)) {
  483. // 设置标签页标题为文件名
  484. QString fileName = QFileInfo(filePath).fileName();
  485. int currentIndex = currentPageIndex();
  486. if (currentIsPLC_) {
  487. plcPageTitles[currentIndex] = fileName;
  488. ui->plc_tab_widget->setTabText(currentIndex, fileName);
  489. } else {
  490. hmiPageTitles[currentIndex] = fileName;
  491. ui->hmi_tab_widget->setTabText(currentIndex, fileName);
  492. }
  493. } else {
  494. QMessageBox::critical(this, "错误", "保存项目失败");
  495. }
  496. }
  497. void MainWindow::connection()
  498. {
  499. modbusManager->connectToDevice("COM1",QSerialPort::BaudRate(9600),QSerialPort::DataBits(8),QSerialPort::EvenParity,QSerialPort::StopBits(1));
  500. modbusManager->startSimulation(1000);
  501. }
  502. void MainWindow::disconnection()
  503. {
  504. modbusManager->disconnectDevice();
  505. modbusManager->stopSimulation();
  506. }
  507. void MainWindow::updateConnectionStatus(bool connection)
  508. {
  509. if (connection)
  510. {
  511. ui->textEdit->append("连接");
  512. }
  513. else
  514. {
  515. ui->textEdit->append("断开");
  516. }
  517. }
  518. void MainWindow::onListwidgetCurrenttextchanged(const QString &currentText)
  519. {
  520. selectedComponentType = currentText;
  521. }
  522. void MainWindow::onTabCloseRequested(int index)
  523. {
  524. if (currentIsPLC_)
  525. {
  526. plcPageTitles.removeAt(index);
  527. delete plcScenes.takeAt(index);
  528. delete plcViews.takeAt(index);
  529. } else {
  530. hmiPageTitles.removeAt(index);
  531. delete hmiScenes.takeAt(index);
  532. delete hmiViews.takeAt(index);
  533. }
  534. }
  535. void MainWindow::btnInsertClicked()
  536. {
  537. // 1. 找场景中被选中的连线
  538. QList<QGraphicsItem*> selectedItems = plcScenes[currentPageIndex()]->selectedItems();
  539. Connection* selectedConn = nullptr;
  540. for (QGraphicsItem* item : selectedItems) {
  541. selectedConn = dynamic_cast<Connection*>(item);
  542. if (selectedConn) break;
  543. }
  544. if (!selectedConn) {
  545. QMessageBox::warning(this, "提示", "请先选中一条连线");
  546. return;
  547. }
  548. if (selectedComponentType.isEmpty()) {
  549. QMessageBox::warning(this, "提示", "请先在列表中选择要插入的组件");
  550. return;
  551. }
  552. // 2. 计算插入点(中点)
  553. QLineF lf = selectedConn->line();
  554. QPointF insertPos = (lf.p1() + lf.p2()) / 2;
  555. // 3. 删除原连线
  556. Item* from = selectedConn->from_;
  557. Item* to = selectedConn->to_;
  558. Item::AnchorType fromType = selectedConn->fromType_;
  559. Item::AnchorType toType = selectedConn->toType_;
  560. from->removeConnection(selectedConn);
  561. to->removeConnection(selectedConn);
  562. plcScenes[currentPageIndex()]->removeItem(selectedConn);
  563. delete selectedConn;
  564. // 4. 插入新元件
  565. Item* newItem = creatItem(selectedComponentType);
  566. newItem->setPos(insertPos);
  567. connect(newItem, &Item::requestCopy, plcViews[currentPageIndex()], &MyGraphicsView::onItemRequestCopy);
  568. connect(newItem, &Item::requestDelete, plcViews[currentPageIndex()], &MyGraphicsView::onItemRequestDelete);
  569. connect(newItem, &Item::requestBindRegister, plcViews[currentPageIndex()], &MyGraphicsView::onItemRequestBindRegister);
  570. connect(newItem, &Item::requestCompare, plcViews[currentPageIndex()], &MyGraphicsView::onItemRequestCompare);
  571. connect(newItem, &Item::requestReset, plcViews[currentPageIndex()], &MyGraphicsView::onItemRequestReset);
  572. connect(newItem, &Item::requestSetON,plcViews[currentPageIndex()], &MyGraphicsView::onItemRequestSetON);
  573. plcScenes[currentPageIndex()]->addItem(newItem);
  574. // 5. 新建两条连线
  575. Connection* c1 = new Connection(from, fromType, newItem, Item::Left);
  576. plcScenes[currentPageIndex()]->addItem(c1);
  577. Connection* c2 = new Connection(newItem, Item::Right, to, toType);
  578. plcScenes[currentPageIndex()]->addItem(c2);
  579. }