Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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