/** * @file main_window.h * @brief 定义综合平台编程器主窗口及运行模式界面协调逻辑 * @version 0.2.0 * @author suyu * @date 2026-08-08 */ #pragma once #include "domain/hmi_model.h" #include "domain/control_logic_model.h" #include "domain/runtime_state.h" #include "services/plc_communication_gateway.h" #include #include QT_BEGIN_NAMESPACE class QActionGroup; class QLabel; class QTimer; namespace Ui { class MainWindow; } QT_END_NAMESPACE class RuntimeModeService; class ProjectService; class HmiEditorService; class HmiRuntimeService; class HmiEditorWidget; class LogicEditorService; class LogicEditorWidget; class RegisterMonitorService; class RuntimeMonitorWidget; /** * @brief 组织主界面区域并将用户操作转交给服务层 * * 主窗口不直接访问寄存器、工程文件或 PLC 通信实现 */ class MainWindow final : public QMainWindow { Q_OBJECT public: /** * @brief 创建主窗口并注入 UI 所需的应用服务 * @param runtime_mode_service 运行模式服务,调用方必须保证其生命周期覆盖窗口 * @param project_service 工程管理服务,调用方必须保证其生命周期覆盖窗口 * @param hmi_editor_service HMI 编辑服务,调用方必须保证其生命周期覆盖窗口 * @param hmi_runtime_service HMI 运行服务,调用方必须保证其生命周期覆盖窗口 * @param parent Qt 父对象 */ explicit MainWindow( RuntimeModeService &runtime_mode_service, ProjectService &project_service, HmiEditorService &hmi_editor_service, LogicEditorService &logic_editor_service, HmiRuntimeService &hmi_runtime_service, RegisterMonitorService ®ister_monitor_service, QWidget *parent = nullptr); ~MainWindow() override; private: // 配置菜单和工具栏动作 void configureActions(); // 配置主窗口外观和状态栏 void configureAppearance(); // 创建并连接 HMI 编辑画布 void configureHmiEditor(); // 创建并连接控制逻辑编辑画布 void configureLogicEditor(); void configureRuntimeMonitor(); // 创建并连接控件属性编辑表单 void configurePropertyEditor(); void configurePlcConnection(); // 刷新工程树和当前 HMI 页面信息 void refreshProjectUi(); // 显示指定 HMI 控件的可编辑属性 void showControlProperties(const std::string &control_id); // 显示指定控制逻辑节点的可编辑属性 void showLogicNodeProperties(const std::string &node_id); // 向当前页面添加指定类型的 HMI 控件 void addHmiControl(HmiControlType type); // 删除当前选中的 HMI 控件 void deleteSelectedControl(); // 将属性表单内容应用到当前选中控件 void applySelectedControlProperties(); // 在当前光标节点后添加串联条件,没有选择时追加到网络末尾 void addLogicCondition(const LogicNodeConfig &config); // 为当前选中的连续逻辑范围建立并联支路 void addLogicParallelBranch(const LogicNodeConfig &config); // 设置当前网络右侧的输出线圈 void setLogicOutput(const LogicNodeConfig &config); // 新增一个梯形图网络 void addLogicRung(); // 删除当前选中的逻辑节点或网络 void deleteSelectedLogicObject(); // 将逻辑属性表单内容应用到当前选中节点 void applySelectedLogicNodeProperties(); void connectPlc(); void disconnectPlc(); // 合并同一事件循环内的 PLC 状态通知,避免重复刷新和重复日志 void schedulePlcStatusUpdate(); // 创建新的工程并刷新编辑界面 void createNewProject(); // 保存当前工程到已关联的路径 void saveProject(); // 将当前工程保存到用户指定的路径 void saveProjectAs(); // 从用户指定的路径加载工程 void loadProject(); // 在状态栏和输出面板显示工程操作结果 void showProjectResult(const QString &action, const QString &message, bool succeeded); /** * @brief 请求服务层切换模式并同步界面状态 * @param requested_mode 目标应用模式 * * 失败时恢复与服务层当前状态一致的工具栏选项 */ void requestMode(ApplicationMode requested_mode); /** * @brief 根据服务层模式策略更新编辑权限和状态反馈 * @param message 要显示在状态栏和输出区的模式结果消息 */ void updateModeUi(const QString &message); // 根据仿真服务实际状态刷新执行器反馈和 HMI 写权限 void updateSimulationUi(bool report_fault); /** * @brief 将互斥模式动作同步到服务层当前状态 */ void restoreCurrentModeAction(); std::unique_ptr ui_; /** * @brief 非拥有的运行模式服务依赖,由应用入口保证生命周期 */ RuntimeModeService &runtime_mode_service_; /** * @brief 非拥有的工程和 HMI 服务依赖,由应用入口保证生命周期 */ ProjectService &project_service_; HmiEditorService &hmi_editor_service_; LogicEditorService &logic_editor_service_; HmiRuntimeService &hmi_runtime_service_; RegisterMonitorService ®ister_monitor_service_; QActionGroup *mode_action_group_ = nullptr; HmiEditorWidget *hmi_editor_widget_ = nullptr; LogicEditorWidget *logic_editor_widget_ = nullptr; RuntimeMonitorWidget *runtime_monitor_widget_ = nullptr; QTimer *runtime_refresh_timer_ = nullptr; QLabel *mode_status_label_ = nullptr; QLabel *register_status_label_ = nullptr; QLabel *executor_status_label_ = nullptr; PlcSerialConfiguration plc_configuration_; std::string selected_control_id_; std::string selected_logic_node_id_; bool plc_status_update_pending_ = false; int last_editing_tab_index_ = 0; };