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.

209 line
6.2 KiB

  1. #include "hmi.h"
  2. #include "ui_hmi.h"
  3. #include <QListWidgetItem>
  4. #include <QMimeData>
  5. #include <QDrag>
  6. #include <QPainter>
  7. #include <QMouseEvent>
  8. #include <QDropEvent>
  9. #include <QGraphicsView>
  10. #include <QMessageBox>
  11. #include <QVBoxLayout>
  12. #include "creatitem.h"
  13. HMI::HMI(QWidget *parent) :
  14. QWidget(parent),
  15. ui(new Ui::HMI)
  16. {
  17. ui->setupUi(this);
  18. ui->tabWidget->setTabsClosable(true);
  19. ui->tabWidget->setMovable(true);
  20. /* 2. 列表 */
  21. ui->listWidget->setViewMode(QListView::IconMode);
  22. ui->listWidget->setIconSize(QSize(60, 30));
  23. ui->listWidget->setDragEnabled(false);
  24. ui->listWidget->viewport()->installEventFilter(this);
  25. // 创建初始页面
  26. newPage();
  27. /* 3. 填充列表 */
  28. createComponents();
  29. connect(ui->listWidget,&QListWidget::currentTextChanged,this,&HMI::onListwidgetCurrenttextchanged);
  30. // 连接标签页信号
  31. // connect(ui->tabWidget, &QTabWidget::currentChanged, this, &HMI::onTabChanged);
  32. connect(ui->tabWidget, &QTabWidget::tabCloseRequested, [this](int index) {
  33. if (scenes.size() > 1) {
  34. delete scenes.takeAt(index);
  35. delete views.takeAt(index);
  36. ui->tabWidget->removeTab(index);
  37. } else {
  38. QMessageBox::information(this, "提示", "至少保留一个页面");
  39. }
  40. });
  41. }
  42. HMI::~HMI()
  43. {
  44. qDeleteAll(scenes);
  45. qDeleteAll(views);
  46. delete ui;
  47. }
  48. void HMI::newPage()
  49. {
  50. // 创建新场景
  51. QGraphicsScene* newScene = new QGraphicsScene(this);
  52. // 创建新视图
  53. MyGraphicsView* newView = new MyGraphicsView(ui->tabWidget);
  54. newView->setScene(newScene);
  55. newView->setSceneRect(0, 0, 800, 600);
  56. newView->setDragMode(QGraphicsView::RubberBandDrag);
  57. // 添加到标签页
  58. int newIndex = ui->tabWidget->addTab(newView, QString("页面 %1").arg(scenes.size() + 1));
  59. ui->tabWidget->setCurrentIndex(newIndex);
  60. // 保存场景和视图
  61. scenes.append(newScene);
  62. views.append(newView);
  63. }
  64. bool HMI::eventFilter(QObject *obj, QEvent *event)
  65. {
  66. if (obj == ui->listWidget->viewport()) {
  67. static QListWidgetItem *dragItem = nullptr;
  68. static QPoint startPos;
  69. if (event->type() == QEvent::MouseButtonPress) {
  70. auto *me = static_cast<QMouseEvent*>(event);
  71. if (me->button() == Qt::LeftButton) {
  72. dragItem = ui->listWidget->itemAt(me->pos());
  73. startPos = me->pos();
  74. }
  75. } else if (event->type() == QEvent::MouseMove && dragItem) {
  76. auto *me = static_cast<QMouseEvent*>(event);
  77. if ((me->pos() - startPos).manhattanLength()
  78. >= QApplication::startDragDistance()) {
  79. QString type = dragItem->data(Qt::UserRole).toString();
  80. QMimeData *mime = new QMimeData;
  81. mime->setData("application/x-component", type.toUtf8());
  82. QDrag *drag = new QDrag(this);
  83. drag->setMimeData(mime);
  84. drag->setPixmap(dragItem->icon().pixmap(ui->listWidget->iconSize()));
  85. drag->setHotSpot(drag->pixmap().rect().center());
  86. drag->exec(Qt::CopyAction);
  87. dragItem = nullptr;
  88. }
  89. } else if (event->type() == QEvent::MouseButtonRelease) {
  90. dragItem = nullptr;
  91. }
  92. }
  93. return QWidget::eventFilter(obj, event);
  94. }
  95. void HMI::createComponents()
  96. {
  97. struct Comp { QString name; QColor color; };
  98. const QVector<Comp> comps = {
  99. {"按钮", Qt::blue},
  100. {"指示灯", Qt::red}
  101. };
  102. for (const Comp &c : comps) {
  103. QListWidgetItem *it = new QListWidgetItem(c.name, ui->listWidget);
  104. QPixmap pix(60, 30);
  105. pix.fill(Qt::white);
  106. QPainter p(&pix);
  107. p.setRenderHint(QPainter::Antialiasing);
  108. p.setBrush(c.color.lighter(150));
  109. p.setPen(QPen(c.color, 2));
  110. p.drawRoundedRect(QRect(5, 5, 50, 20), 3, 3);
  111. p.setPen(Qt::black);
  112. p.drawText(QRect(5, 5, 50, 20), Qt::AlignCenter, c.name);
  113. it->setIcon(QIcon(pix));
  114. it->setData(Qt::UserRole, c.name);
  115. }
  116. }
  117. void HMI::clearScene()
  118. {
  119. if (currentPageIndex() >= 0 && currentPageIndex() < scenes.size()) {
  120. scenes[currentPageIndex()]->clear();
  121. }
  122. }
  123. int HMI::currentPageIndex() const
  124. {
  125. return ui->tabWidget->currentIndex();
  126. }
  127. void HMI::applyProjectToScene(const Project& proj, int pageIndex)
  128. {
  129. if (pageIndex < 0 || pageIndex >= scenes.size())
  130. return;
  131. scenes[pageIndex]->clear();
  132. QVector<Item*> itemObjs;
  133. for (const auto& d : proj.items_) {
  134. Item* item = creatItem(d.type);
  135. if (!item) continue;
  136. item->setPos(d.x, d.y);
  137. item->setRegisterId(d.registerId);
  138. connect(item, &Item::requestCopy, views[pageIndex], &MyGraphicsView::onItemRequestCopy);
  139. connect(item, &Item::requestDelete, views[pageIndex], &MyGraphicsView::onItemRequestDelete);
  140. connect(item, &Item::requestBindRegister, views[pageIndex], &MyGraphicsView::onItemRequestBindRegister);
  141. scenes[pageIndex]->addItem(item);
  142. itemObjs.append(item);
  143. }
  144. }
  145. void HMI::extractSceneToProject(Project& proj, int pageIndex)
  146. {
  147. if (pageIndex < 0 || pageIndex >= scenes.size()) return;
  148. proj.clear();
  149. QList<Item*> items;
  150. for (QGraphicsItem* gi : scenes[pageIndex]->items()){
  151. if (Item* it = dynamic_cast<Item*>(gi)){
  152. items.append(it);
  153. }
  154. }
  155. for (Item* it : items) {
  156. Project::ItemData d;
  157. d.type = it->itemType();
  158. d.x = it->pos().x();
  159. d.y = it->pos().y();
  160. d.registerId = it->registerId();
  161. proj.items_.append(d);
  162. }
  163. for (QGraphicsItem* gi : scenes[pageIndex]->items()) {
  164. if (Connection* conn = dynamic_cast<Connection*>(gi)) {
  165. int fromIdx = items.indexOf(conn->from_);
  166. int toIdx = items.indexOf(conn->to_);
  167. if (fromIdx >= 0 && toIdx >= 0) {
  168. Project::ConnectionData c;
  169. c.from = fromIdx;
  170. c.to = toIdx;
  171. c.fromType = static_cast<int>(conn->fromType_);
  172. c.toType = static_cast<int>(conn->toType_);
  173. proj.connections_.append(c);
  174. }
  175. }
  176. }
  177. }
  178. void HMI::onListwidgetCurrenttextchanged(const QString &text)
  179. {
  180. selectedComponentType = text;
  181. }