综合平台编程器项目的远程存储
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

225 строки
8.0 KiB

  1. /**
  2. * @file main_window.h
  3. * @brief 定义综合平台编程器主窗口及运行模式界面协调逻辑
  4. * @version 0.2.0
  5. * @author suyu
  6. * @date 2026-08-08
  7. */
  8. #pragma once
  9. #include "domain/hmi_model.h"
  10. #include "domain/control_logic_model.h"
  11. #include "domain/runtime_state.h"
  12. #include "services/plc_communication_gateway.h"
  13. #include <QMainWindow>
  14. #include <memory>
  15. QT_BEGIN_NAMESPACE
  16. class QAction;
  17. class QActionGroup;
  18. class QCloseEvent;
  19. class QEvent;
  20. class QLabel;
  21. namespace Ui {
  22. class MainWindow;
  23. }
  24. QT_END_NAMESPACE
  25. class RuntimeModeService;
  26. class ProjectService;
  27. class HmiEditorService;
  28. class HmiRuntimeService;
  29. class AlarmEditorService;
  30. class AlarmService;
  31. class HmiNavigationService;
  32. class RegisterCommentService;
  33. class HmiEditorWidget;
  34. class LogicEditorService;
  35. class LogicEditorWidget;
  36. class RegisterMonitorService;
  37. class RuntimeMonitorWidget;
  38. class ProjectWorkspaceController;
  39. class PropertyPanelController;
  40. class RuntimePanelController;
  41. /**
  42. * @brief 组织主界面区域并将用户操作转交给服务层
  43. *
  44. * 主窗口不直接访问寄存器、工程文件或 PLC 通信实现
  45. */
  46. class MainWindow final : public QMainWindow
  47. {
  48. Q_OBJECT
  49. public:
  50. /**
  51. * @brief 创建主窗口并注入 UI 所需的应用服务
  52. * @param runtime_mode_service 运行模式服务,调用方必须保证其生命周期覆盖窗口
  53. * @param project_service 工程管理服务,调用方必须保证其生命周期覆盖窗口
  54. * @param hmi_editor_service HMI 编辑服务,调用方必须保证其生命周期覆盖窗口
  55. * @param hmi_runtime_service HMI 运行服务,调用方必须保证其生命周期覆盖窗口
  56. * @param parent Qt 父对象
  57. */
  58. explicit MainWindow(
  59. RuntimeModeService &runtime_mode_service,
  60. ProjectService &project_service,
  61. HmiEditorService &hmi_editor_service,
  62. LogicEditorService &logic_editor_service,
  63. HmiRuntimeService &hmi_runtime_service,
  64. AlarmEditorService &alarm_editor_service,
  65. AlarmService &alarm_service,
  66. RegisterCommentService &register_comment_service,
  67. RegisterMonitorService &register_monitor_service,
  68. QWidget *parent = nullptr);
  69. MainWindow(
  70. RuntimeModeService &runtime_mode_service,
  71. ProjectService &project_service,
  72. HmiEditorService &hmi_editor_service,
  73. LogicEditorService &logic_editor_service,
  74. HmiRuntimeService &hmi_runtime_service,
  75. AlarmEditorService &alarm_editor_service,
  76. AlarmService &alarm_service,
  77. HmiNavigationService &hmi_navigation_service,
  78. RegisterCommentService &register_comment_service,
  79. RegisterMonitorService &register_monitor_service,
  80. QWidget *parent = nullptr);
  81. ~MainWindow() override;
  82. const std::string &currentHmiPageId() const;
  83. const std::string &currentLogicId() const;
  84. protected:
  85. bool eventFilter(QObject *watched, QEvent *event) override;
  86. void closeEvent(QCloseEvent *event) override;
  87. private:
  88. // 配置菜单和工具栏动作
  89. void configureActions();
  90. // 配置主窗口外观和状态栏
  91. void configureAppearance();
  92. // 创建并连接 HMI 编辑画布
  93. void configureHmiEditor();
  94. // 创建并连接控制逻辑编辑画布
  95. void configureLogicEditor();
  96. void configureRuntimeMonitor();
  97. void configureProjectTree();
  98. // 创建并连接控件属性编辑表单
  99. void configurePropertyEditor();
  100. void configurePlcConnection();
  101. void configureAlarms();
  102. void configureRegisterComments();
  103. void undoActiveEditor();
  104. void redoActiveEditor();
  105. void deleteActiveSelection();
  106. void clearActiveSelection();
  107. void updateEditActions();
  108. void clearEditorHistories();
  109. void updateWindowTitle();
  110. bool confirmSaveBeforeDestructiveAction();
  111. // 刷新工程树和当前 HMI 页面信息
  112. void refreshProjectUi();
  113. void updateProjectTreeActions();
  114. // 显示指定 HMI 控件的可编辑属性
  115. void showControlProperties(const std::string &control_id);
  116. // 显示指定控制逻辑节点的可编辑属性
  117. void showLogicNodeProperties(const std::string &node_id);
  118. // 向当前页面添加指定类型的 HMI 控件
  119. void addHmiControl(HmiControlType type);
  120. // 删除当前选中的 HMI 控件
  121. void deleteSelectedControl();
  122. // 在当前光标节点后添加串联条件,没有选择时追加到网络末尾
  123. void addLogicCondition(const LogicNodeConfig &config);
  124. // 为当前选中的连续逻辑范围建立并联支路
  125. void addLogicParallelBranch(const LogicNodeConfig &config);
  126. void addLogicHorizontalWire();
  127. void addLogicVerticalWire();
  128. void deleteLogicHorizontalWire();
  129. void deleteLogicVerticalWire();
  130. // 设置当前网络右侧的输出线圈
  131. void setLogicOutput(const LogicNodeConfig &config);
  132. void configureAndSetLogicOutput(const LogicNodeConfig &config);
  133. // 新增一个梯形图网络
  134. void addLogicRung();
  135. void editSelectedRungComment();
  136. // 删除当前选中的逻辑节点或网络
  137. void deleteSelectedLogicObject();
  138. void connectPlc();
  139. void disconnectPlc();
  140. // 合并同一事件循环内的 PLC 状态通知,避免重复刷新和重复日志
  141. void schedulePlcStatusUpdate();
  142. // 创建新的工程并刷新编辑界面
  143. void createNewProject();
  144. // 保存当前工程到已关联的路径
  145. void saveProject();
  146. // 将当前工程保存到用户指定的路径
  147. void saveProjectAs();
  148. // 从用户指定的路径加载工程
  149. void loadProject();
  150. // 在状态栏和输出面板显示工程操作结果
  151. void showProjectResult(const QString &action, const QString &message, bool succeeded);
  152. void appendOutputMessage(const QString &message);
  153. /**
  154. * @brief 请求服务层切换模式并同步界面状态
  155. * @param requested_mode 目标应用模式
  156. *
  157. * 失败时恢复与服务层当前状态一致的工具栏选项
  158. */
  159. void requestMode(ApplicationMode requested_mode);
  160. /**
  161. * @brief 根据服务层模式策略更新编辑权限和状态反馈
  162. * @param message 要显示在状态栏和输出区的模式结果消息
  163. */
  164. void updateModeUi(const QString &message);
  165. // 根据仿真服务实际状态刷新执行器反馈和 HMI 写权限
  166. void updateSimulationUi(bool report_fault);
  167. /**
  168. * @brief 将互斥模式动作同步到服务层当前状态
  169. */
  170. void restoreCurrentModeAction();
  171. void initializeUi();
  172. std::unique_ptr<Ui::MainWindow> ui_;
  173. /**
  174. * @brief 非拥有的运行模式服务依赖,由应用入口保证生命周期
  175. */
  176. RuntimeModeService &runtime_mode_service_;
  177. /**
  178. * @brief 非拥有的工程和 HMI 服务依赖,由应用入口保证生命周期
  179. */
  180. ProjectService &project_service_;
  181. HmiEditorService &hmi_editor_service_;
  182. LogicEditorService &logic_editor_service_;
  183. HmiRuntimeService &hmi_runtime_service_;
  184. AlarmEditorService &alarm_editor_service_;
  185. AlarmService &alarm_service_;
  186. RegisterCommentService &register_comment_service_;
  187. RegisterMonitorService &register_monitor_service_;
  188. std::unique_ptr<HmiNavigationService> owned_hmi_navigation_service_;
  189. HmiNavigationService *hmi_navigation_service_ = nullptr;
  190. std::unique_ptr<ProjectWorkspaceController> project_workspace_controller_;
  191. std::unique_ptr<PropertyPanelController> property_panel_controller_;
  192. std::unique_ptr<RuntimePanelController> runtime_panel_controller_;
  193. QActionGroup *mode_action_group_ = nullptr;
  194. HmiEditorWidget *hmi_editor_widget_ = nullptr;
  195. LogicEditorWidget *logic_editor_widget_ = nullptr;
  196. RuntimeMonitorWidget *runtime_monitor_widget_ = nullptr;
  197. QLabel *mode_status_label_ = nullptr;
  198. QLabel *register_status_label_ = nullptr;
  199. QLabel *executor_status_label_ = nullptr;
  200. PlcSerialConfiguration plc_configuration_;
  201. std::string selected_control_id_;
  202. std::string selected_logic_node_id_;
  203. std::string current_hmi_page_id_;
  204. std::string current_logic_id_;
  205. bool plc_status_update_pending_ = false;
  206. int last_editing_tab_index_ = 0;
  207. };