Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

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