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

155 行
5.5 KiB

  1. #include "hmimodule.h"
  2. #include <QGraphicsScene>
  3. #include <QGraphicsView> // --- 确保包含 QGraphicsView 头文件 ---
  4. #include <QDateTime>
  5. // HMIModule 构造函数无需改动
  6. HMIModule::HMIModule(Ui::MainWindow* ui, QObject *parent)
  7. : QObject{parent}, ui_(ui), m_scene(nullptr)
  8. {}
  9. // 封装设置图标和大小的通用函数
  10. void HMIModule::setButtonIcon(QAbstractButton *button, const QString &iconPath)
  11. {
  12. button->setIcon(QIcon(iconPath));
  13. button->setIconSize(QSize(30, 30));
  14. }
  15. void HMIModule::init() {
  16. setButtonIcon(ui_->button, ":/resource/image/button.png");
  17. setButtonIcon(ui_->lamp, ":/resource/image/lamp.png");
  18. setButtonIcon(ui_->addPage, ":/resource/image/add.png");
  19. setButtonIcon(ui_->deletePage, ":/resource/image/delete.png");
  20. setButtonIcon(ui_->prePage, ":/resource/image/pre.png");
  21. setButtonIcon(ui_->nextPage, ":/resource/image/next.png");
  22. if (!ui_->hmiGraphicsView->scene()) {
  23. // 创建场景时,将 view 指针传入
  24. m_scene = new CustomGraphicsScene(ui_->hmiGraphicsView, this);
  25. m_scene->setSceneRect(0, 0, 800, 600);
  26. ui_->hmiGraphicsView->setScene(m_scene);
  27. } else {
  28. m_scene = qobject_cast<CustomGraphicsScene*>(ui_->hmiGraphicsView->scene());
  29. Q_ASSERT(m_scene);
  30. }
  31. connect(ui_->button, &QPushButton::clicked, this, &HMIModule::prepareToCreateButton);
  32. connect(ui_->lamp, &QPushButton::clicked, this, &HMIModule::prepareToCreateIndicator);
  33. connect(m_scene, &CustomGraphicsScene::componentCreated, this, &HMIModule::onComponentCreated);
  34. // 连接来自场景的键盘事件信号
  35. connect(m_scene, &CustomGraphicsScene::copyRequestFromScene, this, &HMIModule::onCopyRequested);
  36. connect(m_scene, &CustomGraphicsScene::pasteRequestFromScene, this, &HMIModule::onPasteRequested);
  37. connect(m_scene, &CustomGraphicsScene::deleteRequestFromScene, this, &HMIModule::onDeleteRequested);
  38. }
  39. // 辅助函数,用于设置新创建的组件
  40. void HMIModule::setupNewComponent(HmiComponent* item)
  41. {
  42. if (!item) return;
  43. // 连接所有需要的信号
  44. connect(item, &HmiComponent::selected, this, &HMIModule::onComponentSelected);
  45. connect(item, &HmiComponent::copyRequested, this, &HMIModule::onCopyRequested);
  46. connect(item, &HmiComponent::deleteRequested, this, &HMIModule::onDeleteRequested);
  47. // 生成日志
  48. QString currentTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
  49. QString log = QString("[%1] 创建 %2 组件")
  50. .arg(currentTime)
  51. .arg(item->componentName());
  52. emit logMessageGenerated(log);
  53. }
  54. // 准备创建按钮的槽函数
  55. void HMIModule::prepareToCreateButton()
  56. {
  57. m_scene->setComponentTypeToCreate(ComponentType::Button);
  58. m_scene->setMode(CustomGraphicsScene::Mode::CreateItem);
  59. }
  60. // 准备创建指示灯的槽函数
  61. void HMIModule::prepareToCreateIndicator()
  62. {
  63. m_scene->setComponentTypeToCreate(ComponentType::Indicator);
  64. m_scene->setMode(CustomGraphicsScene::Mode::CreateItem);
  65. }
  66. // 处理新创建组件的槽函数
  67. void HMIModule::onComponentCreated(HmiComponent* item)
  68. {
  69. setupNewComponent(item);
  70. }
  71. void HMIModule::onCopyRequested()
  72. {
  73. QList<QGraphicsItem*> selected = m_scene->selectedItems();
  74. if (selected.isEmpty()) return;
  75. // 只复制第一个选中的项目
  76. HmiComponent* itemToCopy = qgraphicsitem_cast<HmiComponent*>(selected.first());
  77. if (!itemToCopy) return;
  78. // 存储组件信息到 "剪贴板"
  79. if (dynamic_cast<HmiButton*>(itemToCopy)) {
  80. m_copiedType = ComponentType::Button;
  81. } else if (dynamic_cast<HmiIndicator*>(itemToCopy)) {
  82. m_copiedType = ComponentType::Indicator;
  83. }
  84. m_copiedColor = itemToCopy->color();
  85. m_hasCopiedItem = true;
  86. // 日志
  87. emit logMessageGenerated(QString("[%1] 复制组件: %2")
  88. .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
  89. .arg(itemToCopy->componentName()));
  90. }
  91. void HMIModule::onPasteRequested(const QPointF& scenePos)
  92. {
  93. if (!m_hasCopiedItem) return;
  94. HmiComponent* newItem = nullptr;
  95. if (m_copiedType == ComponentType::Button) {
  96. newItem = new HmiButton();
  97. } else {
  98. newItem = new HmiIndicator();
  99. }
  100. if (newItem) {
  101. newItem->setColor(m_copiedColor);
  102. // 为了避免完全重叠,给一个小的偏移量
  103. newItem->setPos(scenePos + QPointF(10, 10));
  104. // 使用辅助函数完成添加和信号连接
  105. // 注意:setupNewComponent内部会再次生成“创建”日志,这里是合理的
  106. setupNewComponent(newItem);
  107. }
  108. }
  109. void HMIModule::onDeleteRequested()
  110. {
  111. QList<QGraphicsItem*> selected = m_scene->selectedItems();
  112. if (selected.isEmpty()) return;
  113. // 日志
  114. emit logMessageGenerated(QString("[%1] 删除 %2 个组件")
  115. .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
  116. .arg(selected.count()));
  117. // 从后往前删,避免迭代器失效问题
  118. for (int i = selected.count() - 1; i >= 0; --i) {
  119. QGraphicsItem* item = selected.at(i);
  120. m_scene->removeItem(item);
  121. delete item; // 释放内存
  122. }
  123. }
  124. // 统一处理选中事件的槽函数,无需修改
  125. void HMIModule::onComponentSelected(HmiComponent* item)
  126. {
  127. // if (item) {
  128. // qDebug() << "Component selected:" << item->componentName()
  129. // << "Color:" << item->color();
  130. // // 未来可以在这里将item对象传递给属性编辑器
  131. // }
  132. }