综合平台编辑器
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

340 行
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. #include <QColorDialog>
  10. HMIModule::HMIModule(Ui::MainWindow* ui, QObject *parent)
  11. : QObject{parent}, ui_(ui), m_scene(nullptr)
  12. {
  13. // 初始化 m_pageOrder
  14. m_pageOrder.append(1); // 初始页面
  15. }
  16. void HMIModule::setButtonIcon(QAbstractButton *button, const QString &iconPath)
  17. {
  18. button->setIcon(QIcon(iconPath));
  19. button->setIconSize(QSize(30, 30));
  20. }
  21. void HMIModule::init() {
  22. setButtonIcon(ui_->button, ":/resource/image/button.png");
  23. setButtonIcon(ui_->lamp, ":/resource/image/lamp.png");
  24. setButtonIcon(ui_->addPage, ":/resource/image/add.png");
  25. setButtonIcon(ui_->deletePage, ":/resource/image/delete.png");
  26. setButtonIcon(ui_->prePage, ":/resource/image/pre.png");
  27. setButtonIcon(ui_->nextPage, ":/resource/image/next.png");
  28. if (!ui_->hmiGraphicsView->scene()) {
  29. m_scene = new CustomGraphicsScene(ui_->hmiGraphicsView, this);
  30. m_scene->setSceneRect(0, 0, 800, 600);
  31. ui_->hmiGraphicsView->setScene(m_scene);
  32. } else {
  33. m_scene = qobject_cast<CustomGraphicsScene*>(ui_->hmiGraphicsView->scene());
  34. Q_ASSERT(m_scene);
  35. }
  36. connect(ui_->button, &QPushButton::clicked, this, &HMIModule::prepareToCreateButton);
  37. connect(ui_->lamp, &QPushButton::clicked, this, &HMIModule::prepareToCreateIndicator);
  38. connect(m_scene, &CustomGraphicsScene::componentCreated, this, &HMIModule::onComponentCreated);
  39. connect(m_scene, &CustomGraphicsScene::copyRequestFromScene, this, &HMIModule::onCopyRequested);
  40. connect(m_scene, &CustomGraphicsScene::pasteRequestFromScene, this, &HMIModule::onPasteRequested);
  41. connect(m_scene, &CustomGraphicsScene::deleteRequestFromScene, this, &HMIModule::onDeleteRequested);
  42. // 连接新增的槽函数
  43. connect(ui_->addPage, &QPushButton::clicked, this, &HMIModule::addPage);
  44. connect(ui_->deletePage, &QPushButton::clicked, this, &HMIModule::deletePage);
  45. connect(ui_->prePage, &QPushButton::clicked, this, &HMIModule::prePage);
  46. connect(ui_->nextPage, &QPushButton::clicked, this, &HMIModule::nextPage);
  47. // 连接信号和槽
  48. connect(this, &HMIModule::pageAdded, this, &HMIModule::onPageAdded);
  49. connect(this, &HMIModule::pageRemoved, this, &HMIModule::onPageRemoved);
  50. }
  51. void HMIModule::setupNewComponent(HmiComponent* item)
  52. {
  53. if (!item) return;
  54. connect(item, &HmiComponent::selected, this, &HMIModule::onComponentSelected);
  55. connect(item, &HmiComponent::copyRequested, this, &HMIModule::onCopyRequested);
  56. connect(item, &HmiComponent::deleteRequested, this, &HMIModule::onDeleteRequested);
  57. connect(item, &HmiComponent::appearanceChangedRequested, this, &HMIModule::onChangeAppearanceRequested); // 连接信号
  58. QString currentTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
  59. QString log = QString("[%1] 创建 %2 组件").arg(currentTime).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. void HMIModule::onChangeAppearanceRequested(HmiComponent* item)
  152. {
  153. QColor color = QColorDialog::getColor(item->color(), nullptr, "选择颜色");
  154. if (color.isValid()) {
  155. item->setColor(color);
  156. }
  157. }
  158. // 添加页面后的槽函数
  159. void HMIModule::onPageAdded(int pageNumber, int index)
  160. {
  161. if (index < m_pageOrder.size()) {
  162. m_pageOrder[index] = pageNumber;
  163. } else {
  164. m_pageOrder.append(pageNumber);
  165. }
  166. }
  167. // 删除页面后的槽函数
  168. void HMIModule::onPageRemoved(int pageNumber, int index)
  169. {
  170. if (index < m_pageOrder.size()) {
  171. m_pageOrder[index] = -1;
  172. }
  173. }
  174. void HMIModule::onComponentSelected(HmiComponent* item)
  175. {
  176. // 不需要任何操作,可以留空
  177. }
  178. // 新增页面的槽函数
  179. void HMIModule::addPage()
  180. {
  181. QTabWidget* tabWidget = ui_->tabWidget_2;
  182. int pageNumber;
  183. int insertIndex = -1;
  184. int tabIndex; // 在此处声明 tabIndex
  185. // 检查是否有可用的页面编号
  186. if (!m_availablePageNumbers.isEmpty()) {
  187. pageNumber = m_availablePageNumbers.first();
  188. m_availablePageNumbers.removeFirst();
  189. // 查找可用的插入位置
  190. for (int i = 0; i < m_pageOrder.size(); ++i) {
  191. if (m_pageOrder[i] == -1) {
  192. insertIndex = i;
  193. break;
  194. }
  195. }
  196. } else {
  197. pageNumber = ++m_pageCount;
  198. }
  199. // 获取 Page 1 的 Scene
  200. CustomGraphicsScene* firstScene = m_scene;
  201. // 创建新的页面部件
  202. QWidget* newPage = new QWidget(tabWidget);
  203. QString pageName = QString("Page %1").arg(pageNumber);
  204. newPage->setObjectName(pageName);
  205. // 创建新的 GraphicsView 和 Scene
  206. QGraphicsView* newGraphicsView = new QGraphicsView(newPage);
  207. CustomGraphicsScene* newScene = new CustomGraphicsScene(newGraphicsView, this);
  208. // 设置 GraphicsView 的大小
  209. QSize newViewSize(691, 381); // 设置为指定的宽度和高度
  210. newGraphicsView->resize(newViewSize);
  211. // 设置 GraphicsScene 的大小与 Page 1 相同
  212. QRectF newSceneRect = firstScene->sceneRect();
  213. newScene->setSceneRect(newSceneRect);
  214. newGraphicsView->setScene(newScene);
  215. // 布局
  216. QVBoxLayout* layout = new QVBoxLayout(newPage);
  217. layout->addWidget(newGraphicsView);
  218. newPage->setLayout(layout);
  219. // 添加到 TabWidget
  220. if (insertIndex != -1) {
  221. tabIndex = insertIndex;
  222. tabWidget->insertTab(tabIndex, newPage, pageName);
  223. } else {
  224. tabIndex = tabWidget->addTab(newPage, pageName);
  225. }
  226. // 连接信号和槽 *******************************************************************
  227. connect(newScene, &CustomGraphicsScene::componentCreated, this, &HMIModule::onComponentCreated);
  228. connect(newScene, &CustomGraphicsScene::copyRequestFromScene, this, &HMIModule::onCopyRequested);
  229. connect(newScene, &CustomGraphicsScene::pasteRequestFromScene, this, &HMIModule::onPasteRequested);
  230. connect(newScene, &CustomGraphicsScene::deleteRequestFromScene, this, &HMIModule::onDeleteRequested);
  231. // 发送 pageAdded 信号
  232. emit pageAdded(pageNumber, tabIndex);
  233. tabWidget->setCurrentWidget(newPage);
  234. // 记录日志
  235. emit logMessageGenerated(QString("[%1] 添加页面: %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(pageName));
  236. }
  237. // 删除页面的槽函数
  238. void HMIModule::deletePage()
  239. {
  240. QTabWidget* tabWidget = ui_->tabWidget_2;
  241. int currentIndex = tabWidget->currentIndex();
  242. if (tabWidget->count() == 1) {
  243. QMessageBox::information(nullptr, "提示", "这是最后一页,不能删除!");
  244. return;
  245. }
  246. if (currentIndex >= 0) {
  247. // 获取要删除的页面
  248. QWidget* currentPage = tabWidget->widget(currentIndex);
  249. QString pageName = tabWidget->tabText(currentIndex);
  250. // 从页面名称中提取页面编号
  251. int pageNumber = pageName.remove("Page ").toInt();
  252. // 将删除的页面编号添加到可用列表中
  253. m_availablePageNumbers.append(pageNumber);
  254. std::sort(m_availablePageNumbers.begin(), m_availablePageNumbers.end());
  255. // 从 TabWidget 中移除页面
  256. tabWidget->removeTab(currentIndex);
  257. // 删除页面
  258. delete currentPage;
  259. // 发送 pageRemoved 信号
  260. emit pageRemoved(pageNumber, currentIndex);
  261. // 记录日志
  262. emit logMessageGenerated(QString("[%1] 删除页面: %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(pageName));
  263. }
  264. }
  265. // 前一页的槽函数
  266. void HMIModule::prePage()
  267. {
  268. QTabWidget* tabWidget = ui_->tabWidget_2;
  269. int currentIndex = tabWidget->currentIndex();
  270. if (currentIndex > 0) {
  271. tabWidget->setCurrentIndex(currentIndex - 1);
  272. }
  273. }
  274. // 后一页的槽函数
  275. void HMIModule::nextPage()
  276. {
  277. QTabWidget* tabWidget = ui_->tabWidget_2;
  278. int currentIndex = tabWidget->currentIndex();
  279. if (currentIndex < tabWidget->count() - 1) {
  280. tabWidget->setCurrentIndex(currentIndex + 1);
  281. }
  282. }