综合平台编辑器
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.

339 rivejä
12 KiB

  1. #include "hmimodule.h"
  2. #include <QGraphicsScene>
  3. #include <QGraphicsView>
  4. #include <QDateTime>
  5. #include <QTabWidget>
  6. #include <QMessageBox>
  7. #include <QVBoxLayout>
  8. #include <algorithm>
  9. HMIModule::HMIModule(Ui::MainWindow* ui, QObject *parent)
  10. : QObject{parent}, ui_(ui), m_scene(nullptr)
  11. {
  12. // 初始化 m_pageOrder
  13. m_pageOrder.append(1); // 初始页面
  14. }
  15. void HMIModule::setButtonIcon(QAbstractButton *button, const QString &iconPath)
  16. {
  17. button->setIcon(QIcon(iconPath));
  18. button->setIconSize(QSize(30, 30));
  19. }
  20. void HMIModule::init() {
  21. setButtonIcon(ui_->button, ":/resource/image/button.png");
  22. setButtonIcon(ui_->lamp, ":/resource/image/lamp.png");
  23. setButtonIcon(ui_->addPage, ":/resource/image/add.png");
  24. setButtonIcon(ui_->deletePage, ":/resource/image/delete.png");
  25. setButtonIcon(ui_->prePage, ":/resource/image/pre.png");
  26. setButtonIcon(ui_->nextPage, ":/resource/image/next.png");
  27. if (!ui_->hmiGraphicsView->scene()) {
  28. m_scene = new CustomGraphicsScene(ui_->hmiGraphicsView, this);
  29. m_scene->setSceneRect(0, 0, 800, 600);
  30. ui_->hmiGraphicsView->setScene(m_scene);
  31. } else {
  32. m_scene = qobject_cast<CustomGraphicsScene*>(ui_->hmiGraphicsView->scene());
  33. Q_ASSERT(m_scene);
  34. }
  35. connect(ui_->button, &QPushButton::clicked, this, &HMIModule::prepareToCreateButton);
  36. connect(ui_->lamp, &QPushButton::clicked, this, &HMIModule::prepareToCreateIndicator);
  37. connect(m_scene, &CustomGraphicsScene::componentCreated, this, &HMIModule::onComponentCreated);
  38. connect(m_scene, &CustomGraphicsScene::copyRequestFromScene, this, &HMIModule::onCopyRequested);
  39. connect(m_scene, &CustomGraphicsScene::pasteRequestFromScene, this, &HMIModule::onPasteRequested);
  40. connect(m_scene, &CustomGraphicsScene::deleteRequestFromScene, this, &HMIModule::onDeleteRequested);
  41. // 连接新增的槽函数
  42. connect(ui_->addPage, &QPushButton::clicked, this, &HMIModule::addPage);
  43. connect(ui_->deletePage, &QPushButton::clicked, this, &HMIModule::deletePage);
  44. connect(ui_->prePage, &QPushButton::clicked, this, &HMIModule::prePage);
  45. connect(ui_->nextPage, &QPushButton::clicked, this, &HMIModule::nextPage);
  46. // 连接信号和槽
  47. connect(this, &HMIModule::pageAdded, this, &HMIModule::onPageAdded);
  48. connect(this, &HMIModule::pageRemoved, this, &HMIModule::onPageRemoved);
  49. }
  50. void HMIModule::setupNewComponent(HmiComponent* item)
  51. {
  52. if (!item) return;
  53. connect(item, &HmiComponent::selected, this, &HMIModule::onComponentSelected);
  54. connect(item, &HmiComponent::copyRequested, this, &HMIModule::onCopyRequested);
  55. connect(item, &HmiComponent::deleteRequested, this, &HMIModule::onDeleteRequested);
  56. QString currentTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
  57. QString log = QString("[%1] 创建 %2 组件")
  58. .arg(currentTime)
  59. .arg(item->componentName());
  60. emit logMessageGenerated(log);
  61. }
  62. void HMIModule::prepareToCreateButton()
  63. {
  64. // 获取当前 TabWidget 中选中的 GraphicsView
  65. QTabWidget* tabWidget = ui_->tabWidget_2;
  66. QWidget* currentPage = tabWidget->currentWidget();
  67. QGraphicsView* currentGraphicsView = currentPage->findChild<QGraphicsView*>();
  68. CustomGraphicsScene* currentScene = qobject_cast<CustomGraphicsScene*>(currentGraphicsView->scene());
  69. if (currentScene) {
  70. currentScene->setComponentTypeToCreate(ComponentType::Button);
  71. currentScene->setMode(CustomGraphicsScene::Mode::CreateItem);
  72. }
  73. }
  74. void HMIModule::prepareToCreateIndicator()
  75. {
  76. // 获取当前 TabWidget 中选中的 GraphicsView
  77. QTabWidget* tabWidget = ui_->tabWidget_2;
  78. QWidget* currentPage = tabWidget->currentWidget();
  79. QGraphicsView* currentGraphicsView = currentPage->findChild<QGraphicsView*>();
  80. CustomGraphicsScene* currentScene = qobject_cast<CustomGraphicsScene*>(currentGraphicsView->scene());
  81. if (currentScene) {
  82. currentScene->setComponentTypeToCreate(ComponentType::Indicator);
  83. currentScene->setMode(CustomGraphicsScene::Mode::CreateItem);
  84. }
  85. }
  86. void HMIModule::onComponentCreated(HmiComponent* item)
  87. {
  88. setupNewComponent(item);
  89. }
  90. void HMIModule::onCopyRequested()
  91. {
  92. // 获取当前 TabWidget 中选中的 GraphicsView
  93. QTabWidget* tabWidget = ui_->tabWidget_2;
  94. QWidget* currentPage = tabWidget->currentWidget();
  95. QGraphicsView* currentGraphicsView = currentPage->findChild<QGraphicsView*>();
  96. CustomGraphicsScene* currentScene = qobject_cast<CustomGraphicsScene*>(currentGraphicsView->scene());
  97. QList<QGraphicsItem*> selected = currentScene->selectedItems();
  98. if (selected.isEmpty()) return;
  99. HmiComponent* itemToCopy = qgraphicsitem_cast<HmiComponent*>(selected.first());
  100. if (!itemToCopy) return;
  101. if (dynamic_cast<HmiButton*>(itemToCopy)) {
  102. m_copiedType = ComponentType::Button;
  103. } else if (dynamic_cast<HmiIndicator*>(itemToCopy)) {
  104. m_copiedType = ComponentType::Indicator;
  105. }
  106. m_copiedColor = itemToCopy->color();
  107. m_hasCopiedItem = true;
  108. emit logMessageGenerated(QString("[%1] 复制组件: %2")
  109. .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
  110. .arg(itemToCopy->componentName()));
  111. }
  112. void HMIModule::onPasteRequested(const QPointF& scenePos)
  113. {
  114. if (!m_hasCopiedItem) return;
  115. // 获取当前 TabWidget 中选中的 GraphicsView
  116. QTabWidget* tabWidget = ui_->tabWidget_2;
  117. QWidget* currentPage = tabWidget->currentWidget();
  118. QGraphicsView* currentGraphicsView = currentPage->findChild<QGraphicsView*>();
  119. CustomGraphicsScene* currentScene = qobject_cast<CustomGraphicsScene*>(currentGraphicsView->scene());
  120. HmiComponent* newItem = nullptr;
  121. if (m_copiedType == ComponentType::Button) {
  122. newItem = new HmiButton();
  123. } else {
  124. newItem = new HmiIndicator();
  125. }
  126. if (newItem) {
  127. newItem->setColor(m_copiedColor);
  128. newItem->setPos(scenePos);
  129. currentScene->addItem(newItem); // 使用当前页面的 scene
  130. setupNewComponent(newItem);
  131. }
  132. }
  133. void HMIModule::onDeleteRequested()
  134. {
  135. // 获取当前 TabWidget 中选中的 GraphicsView
  136. QTabWidget* tabWidget = ui_->tabWidget_2;
  137. QWidget* currentPage = tabWidget->currentWidget();
  138. QGraphicsView* currentGraphicsView = currentPage->findChild<QGraphicsView*>();
  139. CustomGraphicsScene* currentScene = qobject_cast<CustomGraphicsScene*>(currentGraphicsView->scene());
  140. QList<QGraphicsItem*> selected = currentScene->selectedItems();
  141. if (selected.isEmpty()) return;
  142. emit logMessageGenerated(QString("[%1] 删除 %2 个组件")
  143. .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
  144. .arg(selected.count()));
  145. for (int i = selected.count() - 1; i >= 0; --i) {
  146. QGraphicsItem* item = selected.at(i);
  147. currentScene->removeItem(item); // 使用当前页面的 scene
  148. delete item;
  149. }
  150. }
  151. // 添加页面后的槽函数
  152. void HMIModule::onPageAdded(int pageNumber, int index)
  153. {
  154. if (index < m_pageOrder.size()) {
  155. m_pageOrder[index] = pageNumber;
  156. } else {
  157. m_pageOrder.append(pageNumber);
  158. }
  159. }
  160. // 删除页面后的槽函数
  161. void HMIModule::onPageRemoved(int pageNumber, int index)
  162. {
  163. if (index < m_pageOrder.size()) {
  164. m_pageOrder[index] = -1;
  165. }
  166. }
  167. // 确保提供 HMIModule::onComponentSelected 的定义
  168. void HMIModule::onComponentSelected(HmiComponent* item)
  169. {
  170. // 在这里添加你的代码
  171. // 如果不需要任何操作,可以留空
  172. }
  173. // 新增页面的槽函数
  174. void HMIModule::addPage()
  175. {
  176. QTabWidget* tabWidget = ui_->tabWidget_2;
  177. int pageNumber;
  178. int insertIndex = -1;
  179. // 检查是否有可用的页面编号
  180. if (!m_availablePageNumbers.isEmpty()) {
  181. pageNumber = m_availablePageNumbers.first();
  182. m_availablePageNumbers.removeFirst();
  183. // 查找可用的插入位置
  184. for (int i = 0; i < m_pageOrder.size(); ++i) {
  185. if (m_pageOrder[i] == -1) {
  186. insertIndex = i;
  187. break;
  188. }
  189. }
  190. } else {
  191. pageNumber = ++m_pageCount;
  192. }
  193. // 获取 Page 1 的 GraphicsView
  194. QGraphicsView* firstGraphicsView = ui_->hmiGraphicsView;
  195. CustomGraphicsScene* firstScene = m_scene; // 获取 Page 1 的 Scene
  196. // 创建新的页面部件
  197. QWidget* newPage = new QWidget(tabWidget);
  198. QString pageName = QString("Page %1").arg(pageNumber);
  199. newPage->setObjectName(pageName);
  200. // 创建新的 GraphicsView 和 Scene
  201. QGraphicsView* newGraphicsView = new QGraphicsView(newPage);
  202. CustomGraphicsScene* newScene = new CustomGraphicsScene(newGraphicsView, this);
  203. // 设置 GraphicsView 的大小,上下左右各扩大 10 像素
  204. QSize newViewSize = firstGraphicsView->size();
  205. newViewSize.setWidth(newViewSize.width() + 20); // 左右各增加 10 像素
  206. newViewSize.setHeight(newViewSize.height() + 20); // 上下各增加 10 像素
  207. newGraphicsView->resize(newViewSize);
  208. // 设置 GraphicsScene 的大小与 Page 1 相同
  209. QRectF newSceneRect = firstScene->sceneRect();
  210. newScene->setSceneRect(newSceneRect);
  211. newGraphicsView->setScene(newScene);
  212. // 布局
  213. QVBoxLayout* layout = new QVBoxLayout(newPage);
  214. layout->addWidget(newGraphicsView);
  215. newPage->setLayout(layout);
  216. // 添加到 TabWidget
  217. int tabIndex;
  218. if (insertIndex != -1) {
  219. tabIndex = insertIndex;
  220. tabWidget->insertTab(tabIndex, newPage, pageName);
  221. } else {
  222. tabIndex = tabWidget->addTab(newPage, pageName);
  223. }
  224. // 连接信号和槽 *******************************************************************
  225. connect(newScene, &CustomGraphicsScene::componentCreated, this, &HMIModule::onComponentCreated);
  226. connect(newScene, &CustomGraphicsScene::copyRequestFromScene, this, &HMIModule::onCopyRequested);
  227. connect(newScene, &CustomGraphicsScene::pasteRequestFromScene, this, &HMIModule::onPasteRequested);
  228. connect(newScene, &CustomGraphicsScene::deleteRequestFromScene, this, &HMIModule::onDeleteRequested);
  229. // *****************************************************************************
  230. // 发送 pageAdded 信号
  231. emit pageAdded(pageNumber, tabIndex);
  232. tabWidget->setCurrentWidget(newPage);
  233. // 记录日志
  234. emit logMessageGenerated(QString("[%1] 添加页面: %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(pageName));
  235. }
  236. // 删除页面的槽函数
  237. void HMIModule::deletePage()
  238. {
  239. QTabWidget* tabWidget = ui_->tabWidget_2;
  240. int currentIndex = tabWidget->currentIndex();
  241. if (tabWidget->count() == 1) {
  242. QMessageBox::information(nullptr, "提示", "这是最后一页,不能删除!");
  243. return;
  244. }
  245. if (currentIndex >= 0) {
  246. // 获取要删除的页面
  247. QWidget* currentPage = tabWidget->widget(currentIndex);
  248. QString pageName = tabWidget->tabText(currentIndex);
  249. // 从页面名称中提取页面编号
  250. int pageNumber = pageName.remove("Page ").toInt();
  251. // 将删除的页面编号添加到可用列表中
  252. m_availablePageNumbers.append(pageNumber);
  253. std::sort(m_availablePageNumbers.begin(), m_availablePageNumbers.end());
  254. // 从 TabWidget 中移除页面
  255. tabWidget->removeTab(currentIndex);
  256. // 删除页面
  257. delete currentPage;
  258. // 发送 pageRemoved 信号
  259. emit pageRemoved(pageNumber, currentIndex);
  260. // 记录日志
  261. emit logMessageGenerated(QString("[%1] 删除页面: %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(pageName));
  262. }
  263. }
  264. // 前一页的槽函数
  265. void HMIModule::prePage()
  266. {
  267. QTabWidget* tabWidget = ui_->tabWidget_2;
  268. int currentIndex = tabWidget->currentIndex();
  269. if (currentIndex > 0) {
  270. tabWidget->setCurrentIndex(currentIndex - 1);
  271. }
  272. }
  273. // 后一页的槽函数
  274. void HMIModule::nextPage()
  275. {
  276. QTabWidget* tabWidget = ui_->tabWidget_2;
  277. int currentIndex = tabWidget->currentIndex();
  278. if (currentIndex < tabWidget->count() - 1) {
  279. tabWidget->setCurrentIndex(currentIndex + 1);
  280. }
  281. }