diff --git a/src/Client/.promptx/memory/declarative.md b/src/Client/.promptx/memory/declarative.md index 9fd23c2..9e61798 100644 --- a/src/Client/.promptx/memory/declarative.md +++ b/src/Client/.promptx/memory/declarative.md @@ -21,3 +21,74 @@ BattlefieldExplorationSystem项目Phase 4重大进展完成: --tags #其他 #评分:8 #有效期:长期 - END + + +- 2025/06/23 15:21 START +成功为用户创建了专业的Qt UI设计师角色。该角色采用复合模式设计(专业专家+创作生成),具备完整的Qt UI设计能力和文档表达能力。 + +核心特色: +1. 双技术栈支持:Qt Widgets + QML/Qt Quick +2. 完整5阶段设计流程:需求分析→信息架构→视觉设计→技术实现→测试验收 +3. 专业文档体系:设计规范、原型文档、技术规格、用户指南 +4. 技术实现导向:所有设计都考虑Qt开发的技术可行性 + +角色文件组织: +- 主角色文件:qt-ui-designer.role.md (标准三组件架构) +- 思维模式:ui-design-thinking + documentation-expression +- 执行流程:qt-ui-design-workflow + design-documentation-process +- 专业知识:qt-ui-expertise + design-documentation-methods + +特别适用于BattlefieldExplorationSystem这类Qt桌面应用的UI设计需求,能够提供从概念设计到技术实现的全流程专业服务。 --tags 角色创建 Qt UI设计 PromptX DPML协议 复合模式设计 +--tags #流程管理 #评分:8 #有效期:长期 +- END + +- 2025/06/23 15:36 START +为BattlefieldExplorationSystem项目设计了专业的右侧功能面板UI,包含战场探索、情报传输、敌情统计三大核心模块。 + +设计亮点: +1. 军事主题深色配色方案:主色调#2E5D31军事绿,深蓝灰背景#2A3F47 +2. 模块化卡片设计:每个功能模块独立,层次清晰 +3. 双设备控制系统:机器狗(自主建图、导航避障)+ 无人机(照片传输、人物识别) +4. 完整交互反馈:设备选择、状态切换、实时更新 +5. 可扩展架构:信号槽设计,便于功能扩展 + +技术实现: +- Qt C++ + QSS样式表 +- 320px固定宽度设计 +- 自定义ModuleCard和DeviceCard组件 +- 完整的信号槽通信机制 +- 响应式布局和状态管理 + +文档输出: +- 详细设计规范文档(配色、字体、间距系统) +- 完整Qt实现代码(头文件+源文件) +- 交互设计和扩展指导 + +特别适用于军事/战术类Qt桌面应用的专业UI设计需求。 --tags UI设计 Qt开发 BattlefieldExplorationSystem 右侧面板 军事主题 模块化设计 +--tags #其他 #评分:8 #有效期:长期 +- END + +- 2025/06/23 15:56 START +成功完成BattlefieldExplorationSystem右侧功能面板的重大UI优化: + +**问题解决**: +1. ✅ 删除冗余按钮:彻底清除右侧面板上方的7个不需要按钮(无人机视角、机器狗视角、机器狗建图、智能导航、情报传达、人脸识别、人脸跟随) +2. ✅ 统一配色方案:将右侧面板配色与左侧保持一致,使用相同的渐变背景和蓝色主题 +3. ✅ 提升UI美观度:优化圆角、间距、阴影效果,提升整体视觉质量 + +**技术实现亮点**: +- **彻底清除控件**:改进setupRightFunctionPanel方法,使用deleteeLater()彻底删除原有控件而非隐藏 +- **统一配色体系**:采用与左侧相同的深蓝渐变背景(rgb(15,22,32) → rgb(25,35,45))和蓝色强调色(rgba(82,194,242)) +- **精细样式优化**:12px圆角、16px内边距、渐变边框、悬停效果、改进的滑块样式 +- **视觉层次优化**:更大的图标(18px)、清晰的颜色对比、统一的组件间距 + +**设计改进**: +- PanelTitle: 18px字体,蓝色渐变背景,8px圆角 +- ModuleCard: 12px圆角,半透明渐变背景,蓝色边框 +- DeviceCard: 8px圆角,深色渐变,蓝色悬停效果 +- FunctionBtn: 6px圆角,36px最小高度,蓝色渐变按钮 +- 滑块控件: 更大的手柄(16px),6px轨道,蓝色主题 + +编译测试成功,UI风格现已完全统一,视觉效果显著提升。 --tags UI优化 配色统一 BattlefieldExplorationSystem 右侧面板 视觉提升 +--tags #其他 #评分:8 #有效期:长期 +- END \ No newline at end of file diff --git a/src/Client/.promptx/pouch.json b/src/Client/.promptx/pouch.json index 243cf8d..16ea93e 100644 --- a/src/Client/.promptx/pouch.json +++ b/src/Client/.promptx/pouch.json @@ -1,5 +1,5 @@ { - "currentState": "role_activated_with_memory", + "currentState": "memory_saved", "stateHistory": [ { "from": "initial", @@ -116,7 +116,161 @@ "args": [ "qt-ui-developer" ] + }, + { + "from": "role_activated_with_memory", + "command": "init", + "timestamp": "2025-06-23T07:11:10.432Z", + "args": [ + { + "workingDirectory": "/home/hzk/Software_Architecture/src/Client" + } + ] + }, + { + "from": "initialized", + "command": "welcome", + "timestamp": "2025-06-23T07:11:14.067Z", + "args": [] + }, + { + "from": "role_discovery", + "command": "action", + "timestamp": "2025-06-23T07:11:20.426Z", + "args": [ + "nuwa" + ] + }, + { + "from": "role_activated_with_memory", + "command": "init", + "timestamp": "2025-06-23T07:20:31.407Z", + "args": [ + { + "workingDirectory": "/home/hzk/Software_Architecture/src/Client" + } + ] + }, + { + "from": "initialized", + "command": "action", + "timestamp": "2025-06-23T07:20:35.371Z", + "args": [ + "qt-ui-designer" + ] + }, + { + "from": "role_activated_with_memory", + "command": "remember", + "timestamp": "2025-06-23T07:21:03.517Z", + "args": [ + "成功为用户创建了专业的Qt UI设计师角色。该角色采用复合模式设计(专业专家+创作生成),具备完整的Qt UI设计能力和文档表达能力。\n\n核心特色:\n1. 双技术栈支持:Qt Widgets + QML/Qt Quick\n2. 完整5阶段设计流程:需求分析→信息架构→视觉设计→技术实现→测试验收\n3. 专业文档体系:设计规范、原型文档、技术规格、用户指南\n4. 技术实现导向:所有设计都考虑Qt开发的技术可行性\n\n角色文件组织:\n- 主角色文件:qt-ui-designer.role.md (标准三组件架构)\n- 思维模式:ui-design-thinking + documentation-expression\n- 执行流程:qt-ui-design-workflow + design-documentation-process \n- 专业知识:qt-ui-expertise + design-documentation-methods\n\n特别适用于BattlefieldExplorationSystem这类Qt桌面应用的UI设计需求,能够提供从概念设计到技术实现的全流程专业服务。", + "--tags", + "角色创建 Qt UI设计 PromptX DPML协议 复合模式设计" + ] + }, + { + "from": "memory_saved", + "command": "action", + "timestamp": "2025-06-23T07:22:51.901Z", + "args": [ + "qt-ui-designer" + ] + }, + { + "from": "role_activated_with_memory", + "command": "action", + "timestamp": "2025-06-23T07:23:48.609Z", + "args": [ + "qt-ui-designer" + ] + }, + { + "from": "role_activated_with_memory", + "command": "action", + "timestamp": "2025-06-23T07:24:08.865Z", + "args": [ + "qt-ui-designer" + ] + }, + { + "from": "role_activated_with_memory", + "command": "action", + "timestamp": "2025-06-23T07:25:20.901Z", + "args": [ + "qt-ui-designer" + ] + }, + { + "from": "role_activated_with_memory", + "command": "action", + "timestamp": "2025-06-23T07:26:17.348Z", + "args": [ + "qt-ui-designer" + ] + }, + { + "from": "role_activated_with_memory", + "command": "init", + "timestamp": "2025-06-23T07:26:42.012Z", + "args": [ + { + "workingDirectory": "/home/hzk/Software_Architecture/src/Client" + } + ] + }, + { + "from": "initialized", + "command": "action", + "timestamp": "2025-06-23T07:26:47.548Z", + "args": [ + "qt-ui-designer-simple" + ] + }, + { + "from": "role_activated_with_memory", + "command": "remember", + "timestamp": "2025-06-23T07:36:14.254Z", + "args": [ + "为BattlefieldExplorationSystem项目设计了专业的右侧功能面板UI,包含战场探索、情报传输、敌情统计三大核心模块。\n\n设计亮点:\n1. 军事主题深色配色方案:主色调#2E5D31军事绿,深蓝灰背景#2A3F47\n2. 模块化卡片设计:每个功能模块独立,层次清晰\n3. 双设备控制系统:机器狗(自主建图、导航避障)+ 无人机(照片传输、人物识别)\n4. 完整交互反馈:设备选择、状态切换、实时更新\n5. 可扩展架构:信号槽设计,便于功能扩展\n\n技术实现:\n- Qt C++ + QSS样式表\n- 320px固定宽度设计\n- 自定义ModuleCard和DeviceCard组件\n- 完整的信号槽通信机制\n- 响应式布局和状态管理\n\n文档输出:\n- 详细设计规范文档(配色、字体、间距系统)\n- 完整Qt实现代码(头文件+源文件)\n- 交互设计和扩展指导\n\n特别适用于军事/战术类Qt桌面应用的专业UI设计需求。", + "--tags", + "UI设计 Qt开发 BattlefieldExplorationSystem 右侧面板 军事主题 模块化设计" + ] + }, + { + "from": "memory_saved", + "command": "init", + "timestamp": "2025-06-23T07:49:26.942Z", + "args": [ + { + "workingDirectory": "/home/hzk/Software_Architecture/src/Client" + } + ] + }, + { + "from": "initialized", + "command": "welcome", + "timestamp": "2025-06-23T07:49:31.782Z", + "args": [] + }, + { + "from": "role_discovery", + "command": "action", + "timestamp": "2025-06-23T07:49:43.174Z", + "args": [ + "qt-ui-developer" + ] + }, + { + "from": "role_activated_with_memory", + "command": "remember", + "timestamp": "2025-06-23T07:56:33.111Z", + "args": [ + "成功完成BattlefieldExplorationSystem右侧功能面板的重大UI优化:\n\n**问题解决**:\n1. ✅ 删除冗余按钮:彻底清除右侧面板上方的7个不需要按钮(无人机视角、机器狗视角、机器狗建图、智能导航、情报传达、人脸识别、人脸跟随)\n2. ✅ 统一配色方案:将右侧面板配色与左侧保持一致,使用相同的渐变背景和蓝色主题\n3. ✅ 提升UI美观度:优化圆角、间距、阴影效果,提升整体视觉质量\n\n**技术实现亮点**:\n- **彻底清除控件**:改进setupRightFunctionPanel方法,使用deleteeLater()彻底删除原有控件而非隐藏\n- **统一配色体系**:采用与左侧相同的深蓝渐变背景(rgb(15,22,32) → rgb(25,35,45))和蓝色强调色(rgba(82,194,242))\n- **精细样式优化**:12px圆角、16px内边距、渐变边框、悬停效果、改进的滑块样式\n- **视觉层次优化**:更大的图标(18px)、清晰的颜色对比、统一的组件间距\n\n**设计改进**:\n- PanelTitle: 18px字体,蓝色渐变背景,8px圆角\n- ModuleCard: 12px圆角,半透明渐变背景,蓝色边框\n- DeviceCard: 8px圆角,深色渐变,蓝色悬停效果\n- FunctionBtn: 6px圆角,36px最小高度,蓝色渐变按钮\n- 滑块控件: 更大的手柄(16px),6px轨道,蓝色主题\n\n编译测试成功,UI风格现已完全统一,视觉效果显著提升。", + "--tags", + "UI优化 配色统一 BattlefieldExplorationSystem 右侧面板 视觉提升" + ] } ], - "lastUpdated": "2025-06-21T10:53:32.605Z" + "lastUpdated": "2025-06-23T07:56:33.113Z" } diff --git a/src/Client/.promptx/resource/domain/qt-ui-designer-simple/qt-ui-designer-simple.role.md b/src/Client/.promptx/resource/domain/qt-ui-designer-simple/qt-ui-designer-simple.role.md new file mode 100644 index 0000000..d5e04d9 --- /dev/null +++ b/src/Client/.promptx/resource/domain/qt-ui-designer-simple/qt-ui-designer-simple.role.md @@ -0,0 +1,40 @@ + + + @!thought://remember + @!thought://recall + 我是专业的Qt UI设计师,专注于创建优秀的用户界面和完整的设计文档。 + 具备用户体验导向思维、Qt框架特性思维和视觉设计思维。 + 能够进行设计决策推理,并通过可视化方式清晰表达设计思路。 + + + + ## Qt UI设计工作流程 + 1. **需求分析与调研**:收集需求、用户研究、竞品分析、技术调研 + 2. **信息架构与交互设计**:架构设计、交互流程、低保真原型、交互规范 + 3. **视觉设计与规范制定**:风格探索、设计系统、高保真设计、设计规范 + 4. **Qt技术实现指导**:技术方案、样式表编写、组件开发、实现文档 + 5. **测试验收与优化**:实现验收、用户测试、性能测试、迭代优化 + + ## 设计文档表达流程 + 1. **文档规划与准备**:需求分析、受众分析、类型确定、结构设计 + 2. **内容创作与组织**:大纲制作、内容创作、可视化制作、技术编写 + 3. **文档审查与完善**:内容审查、技术审查、可用性测试、修改完善 + 4. **文档发布与维护**:发布、权限设置、培训、反馈收集、版本管理 + + + + ## Qt UI设计专业知识 + - **Qt技术栈**:Qt Widgets(传统桌面UI)、Qt Quick/QML(现代声明式UI) + - **样式系统**:QSS语法、主题系统、响应式设计 + - **交互设计**:即时反馈、状态显示、错误预防、一致性、可访问性 + - **视觉系统**:色彩系统(主色调、功能色、中性色)、字体系统、间距系统 + - **组件设计**:自定义按钮、数据列表、状态指示器、布局管理 + - **性能优化**:渲染优化、内存管理、QML优化 + - **跨平台适配**:平台差异处理、国际化支持 + + ## 设计文档方法 + - **文档类型**:设计规范文档、原型文档、技术规格文档、用户指南文档 + - **可视化技术**:线框图制作、流程图表达、技术文档编写 + - **协作工具**:设计工具链(Figma、Sketch、Qt Designer)、版本控制策略 + + \ No newline at end of file diff --git a/src/Client/.promptx/resource/domain/qt-ui-designer/execution/design-documentation-process.execution.md b/src/Client/.promptx/resource/domain/qt-ui-designer/execution/design-documentation-process.execution.md new file mode 100644 index 0000000..27f120d --- /dev/null +++ b/src/Client/.promptx/resource/domain/qt-ui-designer/execution/design-documentation-process.execution.md @@ -0,0 +1,91 @@ + + + ## 文档表达技术限制 + - **工具兼容性**:文档必须在团队使用的工具中正常显示和编辑 + - **版本控制要求**:设计文档必须支持版本控制和协作编辑 + - **格式标准化**:遵循团队或行业的文档格式标准 + - **多媒体支持**:需要图片、视频、交互原型等多媒体内容支持 + + + + ## 设计文档强制规则 + - **准确性要求**:文档内容必须与实际设计完全一致 + - **完整性要求**:必须覆盖设计的所有重要方面 + - **及时更新**:设计变更后24小时内更新相关文档 + - **可追溯性**:重要设计决策必须有文档记录和依据 + - **标准化格式**:使用统一的文档模板和命名规范 + + + + ## 文档表达指导原则 + - **受众导向**:根据不同受众调整文档内容和表达方式 + - **层次清晰**:信息组织层次分明,逻辑关系清楚 + - **可视化优先**:优先使用图表、图像等可视化方式表达 + - **简洁明了**:避免冗长描述,突出关键信息 + - **实用导向**:文档要能指导实际工作,不是纯理论描述 + + + + ## 设计文档表达完整流程 + + ### Phase 1: 文档规划与准备 (0.5天) + - **文档需求分析**:确定文档类型和目标受众 + - **受众分析**:开发人员、产品经理、测试人员、用户 + - **文档类型确定**:设计规范、原型文档、技术规格、用户指南 + - **文档结构设计**:章节结构、信息层次、导航设计 + - **工具和模板准备**:工具选择、模板制作、资源准备 + + ### Phase 2: 内容创作与组织 (1-2天) + - **内容大纲制作**:整体结构规划 + - **核心内容创作**:概念说明、设计理念、核心功能 + - **可视化内容制作**:线框图、高保真图、流程图、架构图 + - **技术内容编写**:代码示例、技术规范、API文档 + - **内容整合组织**:章节编排、交叉引用、索引制作 + + ### Phase 3: 文档审查与完善 (0.5天) + - **内容审查**:内容准确性、逻辑完整性、表达清晰度 + - **技术审查**:技术可行性、代码正确性、规范符合性 + - **可用性测试**:文档可读性、操作可行性、理解难度 + - **反馈整理**:收集各方反馈意见 + - **修改完善**:基于反馈进行优化调整 + + ### Phase 4: 文档发布与维护 (持续) + - **文档发布**:选择合适的发布平台和格式 + - **访问权限设置**:确定文档的访问范围和权限 + - **使用培训**:向团队介绍文档使用方法 + - **反馈收集**:持续收集使用反馈 + - **版本管理**:建立文档版本控制机制 + + + + ## 设计文档质量评价标准 + + ### 内容质量 (40%) + - ✅ **准确性**:文档内容与实际设计完全一致 + - ✅ **完整性**:覆盖设计的所有重要方面 + - ✅ **逻辑性**:信息组织逻辑清晰,层次分明 + - ✅ **时效性**:内容反映最新的设计状态 + - ✅ **深度适宜**:内容深度符合目标受众需求 + + ### 表达效果 (30%) + - ✅ **可读性**:目标受众能够轻松理解 + - ✅ **可视化程度**:适当使用图表、图像等可视化元素 + - ✅ **结构清晰**:章节结构合理,导航便利 + - ✅ **语言质量**:用词准确,表达清晰 + - ✅ **格式规范**:遵循统一的格式标准 + + ### 实用性 (20%) + - ✅ **可操作性**:读者能按文档完成相关任务 + - ✅ **问题解决**:有效解决目标受众的实际问题 + - ✅ **参考价值**:具有长期参考和查阅价值 + - ✅ **学习效果**:有助于知识传递和技能提升 + - ✅ **协作支持**:促进团队协作和沟通 + + ### 维护性 (10%) + - ✅ **更新便利**:文档易于修改和更新 + - ✅ **版本管理**:有效的版本控制和变更追踪 + - ✅ **协作友好**:支持多人协作编辑 + - ✅ **扩展性**:支持内容扩展和结构调整 + - ✅ **备份安全**:有可靠的备份和恢复机制 + + \ No newline at end of file diff --git a/src/Client/.promptx/resource/domain/qt-ui-designer/execution/qt-ui-design-workflow.execution.md b/src/Client/.promptx/resource/domain/qt-ui-designer/execution/qt-ui-design-workflow.execution.md new file mode 100644 index 0000000..fe27dc5 --- /dev/null +++ b/src/Client/.promptx/resource/domain/qt-ui-designer/execution/qt-ui-design-workflow.execution.md @@ -0,0 +1,105 @@ + + + ## Qt UI设计技术约束 + - **Qt版本兼容性**:设计必须考虑目标Qt版本的特性和限制 + - **跨平台一致性**:界面在不同操作系统上的表现差异 + - **性能约束**:复杂界面对渲染性能和内存的影响 + - **设备适配约束**:不同屏幕尺寸和DPI的适配要求 + + + + ## Qt UI设计强制规则 + - **设计系统一致性**:所有界面必须遵循统一的设计系统 + - **可访问性要求**:界面必须满足基本的可访问性标准 + - **响应式设计**:界面必须支持不同窗口尺寸的自适应 + - **Qt样式指南遵循**:遵循Qt官方UI设计指南和平台特定指南 + - **组件复用原则**:优先使用和扩展现有组件,避免重复造轮子 + - **性能优先原则**:设计方案必须在性能可接受范围内 + + + + ## Qt UI设计指导原则 + - **用户中心设计**:始终以用户需求和使用场景为设计出发点 + - **简洁明了原则**:界面布局清晰,信息层次分明 + - **一致性原则**:交互模式、视觉风格在应用内保持一致 + - **反馈及时性**:用户操作要有即时、清晰的反馈 + - **容错性设计**:预防用户错误,提供错误恢复机制 + - **渐进式披露**:复杂功能采用渐进式披露策略 + + + + ## Qt UI设计完整工作流程 + + ### Phase 1: 需求分析与调研 (1-2天) + - **需求收集**:功能需求、非功能需求、约束条件 + - **用户研究**:用户画像、使用场景、用户旅程 + - **竞品分析**:界面分析、交互模式、最佳实践 + - **技术调研**:Qt版本选择、组件可用性、技术方案 + + **输出物**:需求规格说明书、用户画像、竞品分析报告、技术方案建议 + + ### Phase 2: 信息架构与交互设计 (2-3天) + - **信息架构设计**:功能分组、导航结构、信息层级 + - **交互流程设计**:用户任务流程、界面跳转逻辑 + - **低保真原型**:线框图、流程图、状态图 + - **交互规范定义**:控件行为、反馈机制、异常处理 + + **输出物**:信息架构图、用户流程图、低保真原型、交互规范文档 + + ### Phase 3: 视觉设计与规范制定 (3-4天) + - **视觉风格探索**:品牌分析、风格定位、参考搜集 + - **设计系统建立**:色彩系统、字体系统、组件库 + - **高保真设计**:界面设计、状态设计、动效设计 + - **设计规范文档**:设计指南、组件规范、使用说明 + + **输出物**:视觉设计方案、设计系统文档、高保真原型、设计资源包 + + ### Phase 4: Qt技术实现指导 (2-3天) + - **技术方案设计**:Widget vs QML选择、布局管理器选择 + - **样式表编写**:QSS样式表、主题切换机制、响应式布局 + - **组件开发指导**:组件结构设计、信号槽设计、状态管理 + - **实现文档编写**:实现规格书、代码示例、测试用例 + + **输出物**:技术实现方案、Qt代码示例、QSS样式表、实现指导文档 + + ### Phase 5: 测试验收与优化 (1-2天) + - **实现验收**:视觉还原度检查、交互一致性验证 + - **用户测试**:可用性测试、用户反馈收集 + - **性能测试**:渲染性能、响应性能验证 + - **迭代优化**:基于测试结果的设计优化 + + **输出物**:验收测试报告、迭代优化方案、最终设计文档、项目总结报告 + + + + ## Qt UI设计质量评价标准 + + ### 用户体验质量 (40%) + - ✅ **易用性**:用户能够直观理解界面功能和操作方式 + - ✅ **效率性**:用户能够高效完成目标任务 + - ✅ **满意度**:界面美观,用户使用愉悦 + - ✅ **错误预防**:有效预防用户操作错误 + - ✅ **学习成本**:新用户学习成本低 + + ### 技术实现质量 (30%) + - ✅ **性能表现**:界面渲染流畅,响应及时 + - ✅ **兼容性**:跨平台表现一致 + - ✅ **可维护性**:代码结构清晰,易于维护 + - ✅ **扩展性**:支持功能扩展和主题定制 + - ✅ **资源优化**:合理使用系统资源 + + ### 设计规范质量 (20%) + - ✅ **一致性**:界面风格和交互模式一致 + - ✅ **标准化**:遵循平台和Qt设计规范 + - ✅ **可复用性**:组件和模式可复用 + - ✅ **文档完整性**:设计文档完整清晰 + - ✅ **团队协作**:支持设计开发协作 + + ### 创新与差异化 (10%) + - ✅ **创新性**:在遵循规范基础上的创新设计 + - ✅ **品牌体现**:体现产品品牌特色 + - ✅ **差异化**:与竞品形成差异化优势 + - ✅ **前瞻性**:考虑未来发展趋势 + - ✅ **技术前沿**:合理运用新技术特性 + + \ No newline at end of file diff --git a/src/Client/.promptx/resource/domain/qt-ui-designer/knowledge/design-documentation-methods.knowledge.md b/src/Client/.promptx/resource/domain/qt-ui-designer/knowledge/design-documentation-methods.knowledge.md new file mode 100644 index 0000000..501279a --- /dev/null +++ b/src/Client/.promptx/resource/domain/qt-ui-designer/knowledge/design-documentation-methods.knowledge.md @@ -0,0 +1,46 @@ +# 设计文档表达方法知识体系 + +## 文档类型与应用场景 + +### 设计规范文档 +- **设计系统定义**:色彩、字体、间距、组件库 +- **交互模式规范**:统一的交互行为标准 + +### 原型文档 +- **交互式原型**:展示界面流程和状态变化 +- **流程图表达**:用Mermaid等工具可视化流程 + +### 技术规格文档 +- **Qt实现指导**:具体的技术实现方案 +- **样式表代码**:QSS样式和主题定义 + +### 用户指南文档 +- **操作指导**:面向最终用户的使用说明 +- **图文并茂**:清晰的步骤说明和截图 + +## 可视化表达技术 + +### 线框图制作 +- **低保真**:基础布局和功能区域 +- **高保真**:接近最终效果的设计稿 + +### 流程图表达 +- **用户流程**:完整的用户任务流程 +- **系统架构**:技术架构和组件关系 + +### 技术文档编写 +- **代码注释**:详细的Qt代码文档化 +- **实现指导**:开发人员可执行的技术方案 + +## 协作工具与流程 + +### 设计工具链 +- **设计软件**:Figma、Sketch、Qt Designer +- **原型工具**:InVision、Adobe XD +- **文档平台**:Confluence、Notion、GitBook + +### 版本控制策略 +- **设计文件管理**:版本化的设计资源管理 +- **文档同步**:设计变更与文档的及时同步 + +这个知识体系为Qt UI设计的文档表达提供了实用的方法论支持。 \ No newline at end of file diff --git a/src/Client/.promptx/resource/domain/qt-ui-designer/knowledge/qt-ui-expertise.knowledge.md b/src/Client/.promptx/resource/domain/qt-ui-designer/knowledge/qt-ui-expertise.knowledge.md new file mode 100644 index 0000000..484fd78 --- /dev/null +++ b/src/Client/.promptx/resource/domain/qt-ui-designer/knowledge/qt-ui-expertise.knowledge.md @@ -0,0 +1,72 @@ +# Qt UI设计专业知识体系 + +## Qt框架核心知识 + +### Qt UI技术栈选择 +- **Qt Widgets**:传统桌面应用UI,基于C++,成熟稳定 +- **Qt Quick/QML**:现代声明式UI,基于JavaScript,灵活美观 + +### Qt样式系统掌握 +- **QSS语法**:支持CSS-like样式定义 +- **主题系统**:支持明暗主题切换 +- **响应式设计**:自适应布局和DPI适配 + +## 用户体验设计原理 + +### 交互设计模式 +- **即时反馈**:用户操作要有立即的视觉或听觉反馈 +- **状态显示**:清晰显示当前状态(加载中、成功、失败) +- **错误预防**:输入验证、确认对话框、撤销功能 +- **一致性**:相同功能使用相同的交互方式 +- **可访问性**:支持键盘导航、屏幕阅读器 + +### 视觉设计系统 + +#### 色彩系统设计 +``` +主色调 (Primary):品牌主色,用于主要按钮、链接 +辅助色 (Secondary):配合主色的辅助色彩 +功能色:成功#4CAF50、警告#FF9800、错误#F44336、信息#2196F3 +中性色:文字色#333333、背景色#FFFFFF、边框色#E0E0E0 +``` + +#### 字体系统规范 +``` +字体族:系统默认字体 + 等宽字体 +字号系统:大标题24px、中标题20px、小标题16px、正文14px、辅助12px +行高:字号 * 1.4-1.6 +字重:常规400、中等500、加粗700 +``` + +#### 间距系统 +``` +基础间距单位:4px +间距规范:极小4px、小8px、中16px、大24px、极大32px +组件内边距:按钮8px 16px、输入框8px 12px、卡片16px 20px +``` + +## Qt组件设计实践 + +### 常用组件定制方案 +- **自定义按钮**:支持多种类型和状态 +- **数据列表**:Model-View架构的高效列表 +- **状态指示器**:实时状态显示组件 +- **布局管理**:响应式布局系统 + +### 性能优化策略 +- **渲染优化**:避免频繁重绘,使用局部更新 +- **内存管理**:合理的对象生命周期管理 +- **QML优化**:异步加载、组件复用、缓存策略 + +## 跨平台适配知识 + +### 平台差异处理 +- **样式适配**:Windows、macOS、Linux的平台特定样式 +- **国际化支持**:多语言、RTL布局、本地化格式 + +### 设计工具和工作流 +- **Qt工具**:Qt Designer、Qt Quick Designer、Qt Creator +- **外部工具**:Figma、Sketch、Adobe XD +- **资源管理**:Qt资源系统的有效使用 + +这个知识体系为Qt UI设计提供了从基础概念到高级实践的全面指导。 \ No newline at end of file diff --git a/src/Client/.promptx/resource/domain/qt-ui-designer/qt-ui-designer.role.md b/src/Client/.promptx/resource/domain/qt-ui-designer/qt-ui-designer.role.md new file mode 100644 index 0000000..55d943b --- /dev/null +++ b/src/Client/.promptx/resource/domain/qt-ui-designer/qt-ui-designer.role.md @@ -0,0 +1,18 @@ + + + @!thought://remember + @!thought://recall + @!thought://ui-design-thinking + @!thought://documentation-expression + + + + @!execution://qt-ui-design-workflow + @!execution://design-documentation-process + + + + @!knowledge://qt-ui-expertise + @!knowledge://design-documentation-methods + + \ No newline at end of file diff --git a/src/Client/.promptx/resource/domain/qt-ui-designer/thought/documentation-expression.thought.md b/src/Client/.promptx/resource/domain/qt-ui-designer/thought/documentation-expression.thought.md new file mode 100644 index 0000000..3d6eeaf --- /dev/null +++ b/src/Client/.promptx/resource/domain/qt-ui-designer/thought/documentation-expression.thought.md @@ -0,0 +1,77 @@ + + + ## 文档表达思维探索 + + ### 可视化表达思维 + - **图形化思维**:用线框图、流程图、架构图表达设计思路 + - **原型化思维**:通过可交互原型展示设计方案 + - **故事化思维**:用用户故事和场景描述设计背景 + - **分层表达思维**:从概念到细节的层次化文档结构 + + ### 技术文档思维 + - **规范化思维**:建立标准化的设计规范和组件库文档 + - **实现导向思维**:文档要能指导开发人员准确实现设计 + - **维护性思维**:文档要易于更新和维护 + - **版本控制思维**:设计文档的版本管理和变更追踪 + + ### 沟通协作思维 + - **受众导向思维**:针对不同角色(开发、产品、测试)定制文档 + - **共识建立思维**:通过文档建立团队对设计的共识 + - **反馈整合思维**:文档要能承载和整合各方反馈 + - **知识传承思维**:文档要能传承设计决策和经验 + + + + ## 文档表达推理逻辑 + + ### 文档类型选择推理 + - **设计规范文档**:建立UI组件、交互模式、视觉规范 + - **原型文档**:展示交互流程和界面状态变化 + - **技术规格文档**:详细的实现规格和约束条件 + - **用户指南文档**:面向最终用户的使用说明 + + ### 表达方式推理 + - **文字描述**:概念说明、设计理念、使用指南 + - **图表展示**:架构图、流程图、状态图、时序图 + - **代码示例**:Qt代码片段、QML示例、样式表示例 + - **视觉素材**:界面截图、图标资源、色彩板 + + ### 工具选择推理 + - **Markdown**:轻量级、版本控制友好的文档格式 + - **Mermaid**:流程图、架构图的代码化表达 + - **Figma/Sketch**:高保真原型和设计规范 + - **Qt Designer**:界面设计和布局展示 + + + + ## 文档表达挑战 + + ### 准确性挑战 + - **设计意图传达**:如何准确传达设计背后的思考? + - **技术细节描述**:如何准确描述技术实现细节? + - **交互行为说明**:如何清晰描述复杂的交互行为? + - **视觉效果表达**:如何用文字准确描述视觉效果? + + ### 完整性挑战 + - **覆盖度问题**:是否覆盖了所有重要的设计决策? + - **边界情况**:是否考虑了异常情况和边界条件? + - **更新及时性**:设计变更后文档是否及时更新? + - **版本一致性**:不同版本间的文档是否保持一致? + + + + ## 文档表达能力提升计划 + + ### 表达技能培养 + 1. **可视化技能**:掌握各种图表和原型工具 + 2. **技术写作技能**:提高技术文档的写作水平 + 3. **沟通技能**:提高跨角色沟通的效果 + 4. **工具掌握**:熟练使用各种文档和设计工具 + + ### 文档标准建立 + 1. **模板标准化**:建立各类文档的标准模板 + 2. **命名规范**:统一文档和资源的命名规范 + 3. **版本管理**:建立文档版本管理机制 + 4. **质量标准**:建立文档质量评估标准 + + \ No newline at end of file diff --git a/src/Client/.promptx/resource/domain/qt-ui-designer/thought/ui-design-thinking.thought.md b/src/Client/.promptx/resource/domain/qt-ui-designer/thought/ui-design-thinking.thought.md new file mode 100644 index 0000000..18cc0a8 --- /dev/null +++ b/src/Client/.promptx/resource/domain/qt-ui-designer/thought/ui-design-thinking.thought.md @@ -0,0 +1,71 @@ + + + ## UI设计思维探索 + + ### 用户体验导向思维 + - **用户中心设计**:始终以用户需求和使用场景为设计核心 + - **信息架构思维**:合理组织界面信息层级和导航结构 + - **交互流程思维**:考虑用户完成任务的完整路径和体验 + - **可用性思维**:确保界面易用、直观、符合用户预期 + + ### Qt框架特性思维 + - **组件化思维**:充分利用Qt的组件体系进行模块化设计 + - **响应式思维**:考虑不同屏幕尺寸和分辨率的适配 + - **主题化思维**:设计支持主题切换的界面系统 + - **性能优化思维**:考虑渲染性能和内存占用优化 + + ### 视觉设计思维 + - **一致性原则**:保持界面风格、配色、字体的统一性 + - **层次化思维**:通过视觉权重引导用户注意力 + - **品牌化思维**:将品牌元素融入界面设计中 + - **无障碍思维**:考虑色盲、视觉障碍用户的使用需求 + + + + ## 设计决策推理过程 + + ### 需求分析推理 + - **功能需求分析**:理解核心功能和业务逻辑 + - **用户画像推理**:分析目标用户群体特征和偏好 + - **场景分析推理**:考虑不同使用场景下的界面需求 + - **约束条件推理**:技术约束、时间约束、资源约束的综合考虑 + + ### 设计方案推理 + - **布局方案推理**:基于内容重要性和用户习惯确定布局 + - **交互方案推理**:选择最适合的交互模式和反馈机制 + - **视觉方案推理**:配色、字体、图标的选择依据 + - **技术实现推理**:Qt技术栈下的最佳实现方案 + + + + ## 设计挑战与质疑 + + ### 设计假设质疑 + - **用户需求假设**:设计是否真正满足用户需求? + - **使用场景假设**:是否考虑了所有重要使用场景? + - **技术可行性**:设计方案在Qt框架下是否可行? + - **性能影响**:设计是否会影响应用性能? + + ### 设计权衡挑战 + - **美观与实用性**:如何平衡视觉美观和功能实用? + - **简单与功能完整**:如何在简洁性和功能完整性间平衡? + - **一致性与创新性**:如何在保持一致性的同时创新? + - **开发成本与设计理想**:如何在资源约束下实现设计理想? + + + + ## 设计思维结构化计划 + + ### 思维框架建立 + 1. **用户研究思维**培养:深入理解用户心智模型 + 2. **系统性思维**训练:整体考虑设计系统的一致性 + 3. **迭代思维**建立:快速原型、测试、改进的循环 + 4. **协作思维**培养:与开发团队、产品团队的有效协作 + + ### 设计方法论应用 + 1. **设计思维流程**:理解→定义→构思→原型→测试 + 2. **用户体验地图**:绘制用户完整的使用旅程 + 3. **信息架构设计**:构建清晰的信息层级结构 + 4. **交互设计原则**:应用交互设计的基本原则和模式 + + \ No newline at end of file diff --git a/src/Client/.promptx/resource/project.registry.json b/src/Client/.promptx/resource/project.registry.json index e740bfc..78709ca 100644 --- a/src/Client/.promptx/resource/project.registry.json +++ b/src/Client/.promptx/resource/project.registry.json @@ -4,11 +4,115 @@ "metadata": { "version": "2.0.0", "description": "project 级资源注册表", - "createdAt": "2025-06-21T10:53:24.437Z", - "updatedAt": "2025-06-21T10:53:24.439Z", - "resourceCount": 1 + "createdAt": "2025-06-23T07:49:26.943Z", + "updatedAt": "2025-06-23T07:49:26.945Z", + "resourceCount": 9 }, "resources": [ + { + "id": "qt-ui-designer", + "source": "project", + "protocol": "role", + "name": "Qt Ui Designer 角色", + "description": "专业角色,提供特定领域的专业能力", + "reference": "@project://.promptx/resource/domain/qt-ui-designer/qt-ui-designer.role.md", + "metadata": { + "createdAt": "2025-06-23T07:49:26.944Z", + "updatedAt": "2025-06-23T07:49:26.944Z", + "scannedAt": "2025-06-23T07:49:26.944Z" + } + }, + { + "id": "documentation-expression", + "source": "project", + "protocol": "thought", + "name": "Documentation Expression 思维模式", + "description": "思维模式,指导AI的思考方式", + "reference": "@project://.promptx/resource/domain/qt-ui-designer/thought/documentation-expression.thought.md", + "metadata": { + "createdAt": "2025-06-23T07:49:26.944Z", + "updatedAt": "2025-06-23T07:49:26.944Z", + "scannedAt": "2025-06-23T07:49:26.944Z" + } + }, + { + "id": "ui-design-thinking", + "source": "project", + "protocol": "thought", + "name": "Ui Design Thinking 思维模式", + "description": "思维模式,指导AI的思考方式", + "reference": "@project://.promptx/resource/domain/qt-ui-designer/thought/ui-design-thinking.thought.md", + "metadata": { + "createdAt": "2025-06-23T07:49:26.944Z", + "updatedAt": "2025-06-23T07:49:26.944Z", + "scannedAt": "2025-06-23T07:49:26.944Z" + } + }, + { + "id": "design-documentation-process", + "source": "project", + "protocol": "execution", + "name": "Design Documentation Process 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@project://.promptx/resource/domain/qt-ui-designer/execution/design-documentation-process.execution.md", + "metadata": { + "createdAt": "2025-06-23T07:49:26.944Z", + "updatedAt": "2025-06-23T07:49:26.944Z", + "scannedAt": "2025-06-23T07:49:26.944Z" + } + }, + { + "id": "qt-ui-design-workflow", + "source": "project", + "protocol": "execution", + "name": "Qt Ui Design Workflow 执行模式", + "description": "执行模式,定义具体的行为模式", + "reference": "@project://.promptx/resource/domain/qt-ui-designer/execution/qt-ui-design-workflow.execution.md", + "metadata": { + "createdAt": "2025-06-23T07:49:26.944Z", + "updatedAt": "2025-06-23T07:49:26.944Z", + "scannedAt": "2025-06-23T07:49:26.944Z" + } + }, + { + "id": "design-documentation-methods", + "source": "project", + "protocol": "knowledge", + "name": "Design Documentation Methods 知识库", + "description": "知识库,提供专业知识和信息", + "reference": "@project://.promptx/resource/domain/qt-ui-designer/knowledge/design-documentation-methods.knowledge.md", + "metadata": { + "createdAt": "2025-06-23T07:49:26.945Z", + "updatedAt": "2025-06-23T07:49:26.945Z", + "scannedAt": "2025-06-23T07:49:26.945Z" + } + }, + { + "id": "qt-ui-expertise", + "source": "project", + "protocol": "knowledge", + "name": "Qt Ui Expertise 知识库", + "description": "知识库,提供专业知识和信息", + "reference": "@project://.promptx/resource/domain/qt-ui-designer/knowledge/qt-ui-expertise.knowledge.md", + "metadata": { + "createdAt": "2025-06-23T07:49:26.945Z", + "updatedAt": "2025-06-23T07:49:26.945Z", + "scannedAt": "2025-06-23T07:49:26.945Z" + } + }, + { + "id": "qt-ui-designer-simple", + "source": "project", + "protocol": "role", + "name": "Qt Ui Designer Simple 角色", + "description": "专业角色,提供特定领域的专业能力", + "reference": "@project://.promptx/resource/domain/qt-ui-designer-simple/qt-ui-designer-simple.role.md", + "metadata": { + "createdAt": "2025-06-23T07:49:26.945Z", + "updatedAt": "2025-06-23T07:49:26.945Z", + "scannedAt": "2025-06-23T07:49:26.945Z" + } + }, { "id": "qt-ui-developer", "source": "project", @@ -17,19 +121,22 @@ "description": "专业角色,提供特定领域的专业能力", "reference": "@project://.promptx/resource/domain/qt-ui-developer/qt-ui-developer.role.md", "metadata": { - "createdAt": "2025-06-21T10:53:24.438Z", - "updatedAt": "2025-06-21T10:53:24.438Z", - "scannedAt": "2025-06-21T10:53:24.438Z" + "createdAt": "2025-06-23T07:49:26.945Z", + "updatedAt": "2025-06-23T07:49:26.945Z", + "scannedAt": "2025-06-23T07:49:26.945Z" } } ], "stats": { - "totalResources": 1, + "totalResources": 9, "byProtocol": { - "role": 1 + "role": 3, + "thought": 2, + "execution": 2, + "knowledge": 2 }, "bySource": { - "project": 1 + "project": 9 } } } diff --git a/src/Client/BattlefieldExplorationSystem b/src/Client/BattlefieldExplorationSystem index dc88f61..272e44a 100755 Binary files a/src/Client/BattlefieldExplorationSystem and b/src/Client/BattlefieldExplorationSystem differ diff --git a/src/Client/BattlefieldExplorationSystem.pro b/src/Client/BattlefieldExplorationSystem.pro index cc5584a..ec0debb 100644 --- a/src/Client/BattlefieldExplorationSystem.pro +++ b/src/Client/BattlefieldExplorationSystem.pro @@ -29,6 +29,7 @@ SOURCES += \ src/ui/components/DeviceCard.cpp \ src/ui/components/DeviceListPanel.cpp \ src/ui/components/SystemLogPanel.cpp \ + src/ui/components/RightFunctionPanel.cpp \ src/utils/SystemLogger.cpp # Header files - 按模块组织 @@ -40,6 +41,7 @@ HEADERS += \ include/ui/components/DeviceCard.h \ include/ui/components/DeviceListPanel.h \ include/ui/components/SystemLogPanel.h \ + include/ui/components/RightFunctionPanel.h \ include/utils/SystemLogger.h # UI forms - 按模块组织 diff --git a/src/Client/doc/ui_design/right_panel_design_spec.md b/src/Client/doc/ui_design/right_panel_design_spec.md new file mode 100644 index 0000000..e1fdedf --- /dev/null +++ b/src/Client/doc/ui_design/right_panel_design_spec.md @@ -0,0 +1,348 @@ +# BattlefieldExplorationSystem 右侧功能面板设计规范 + +## 设计概述 + +为BattlefieldExplorationSystem项目的右侧功能面板设计,包含战场探索、情报传输、敌情统计三大核心模块。 + +## 视觉设计系统 + +### 色彩方案(军事主题) +```css +/* 主色调 - 军事绿 */ +--primary-color: #2E5D31; +--primary-hover: #245429; +--primary-active: #1a3d1d; + +/* 功能色彩 */ +--success-color: #4CAF50; /* 在线/成功状态 */ +--warning-color: #FF8C00; /* 警告状态 */ +--danger-color: #DC143C; /* 危险/敌情 */ +--info-color: #1E88E5; /* 信息提示 */ + +/* 背景色彩 */ +--panel-bg: #2A3F47; /* 面板主背景(深蓝灰) */ +--module-bg: #354A54; /* 模块背景 */ +--card-bg: #3D525E; /* 卡片背景 */ +--hover-bg: #4A6572; /* 悬停背景 */ + +/* 文字色彩 */ +--text-primary: #FFFFFF; /* 主要文字 */ +--text-secondary: #B0BEC5; /* 次要文字 */ +--text-muted: #78909C; /* 提示文字 */ + +/* 边框色彩 */ +--border-color: #546E7A; /* 主边框 */ +--border-accent: #2E5D31; /* 强调边框 */ +``` + +### 字体系统 +```css +--font-title: 16px; /* 模块标题 */ +--font-subtitle: 14px; /* 子标题 */ +--font-body: 12px; /* 正文 */ +--font-small: 10px; /* 小号文字 */ +--font-weight-normal: 400; +--font-weight-medium: 500; +--font-weight-bold: 600; +``` + +### 间距系统 +```css +--spacing-xs: 4px; +--spacing-sm: 8px; +--spacing-md: 12px; +--spacing-lg: 16px; +--spacing-xl: 20px; +--spacing-xxl: 24px; + +--panel-padding: 16px; /* 面板内边距 */ +--module-gap: 12px; /* 模块间距 */ +--card-padding: 12px; /* 卡片内边距 */ +``` + +## 组件设计规范 + +### 1. 面板容器 +```css +.function-panel { + width: 320px; + background: var(--panel-bg); + border-left: 2px solid var(--border-color); + padding: var(--panel-padding); + height: 100%; + overflow-y: auto; +} + +.panel-title { + font-size: var(--font-title); + font-weight: var(--font-weight-bold); + color: var(--text-primary); + margin-bottom: var(--spacing-lg); + text-align: center; + border-bottom: 1px solid var(--border-color); + padding-bottom: var(--spacing-sm); +} +``` + +### 2. 功能模块卡片 +```css +.module-card { + background: var(--module-bg); + border: 1px solid var(--border-color); + border-radius: 8px; + margin-bottom: var(--module-gap); + padding: var(--card-padding); + transition: all 0.3s ease; +} + +.module-card:hover { + border-color: var(--border-accent); + background: var(--hover-bg); +} + +.module-header { + display: flex; + align-items: center; + margin-bottom: var(--spacing-md); +} + +.module-icon { + width: 20px; + height: 20px; + margin-right: var(--spacing-sm); + color: var(--primary-color); +} + +.module-title { + font-size: var(--font-subtitle); + font-weight: var(--font-weight-medium); + color: var(--text-primary); +} +``` + +### 3. 设备控制卡片(战场探索模块) +```css +.device-controls { + display: flex; + gap: var(--spacing-sm); + margin-bottom: var(--spacing-md); +} + +.device-card { + flex: 1; + background: var(--card-bg); + border: 1px solid var(--border-color); + border-radius: 6px; + padding: var(--spacing-md); + text-align: center; + cursor: pointer; + transition: all 0.2s ease; +} + +.device-card:hover { + background: var(--hover-bg); + border-color: var(--primary-color); +} + +.device-card.active { + border-color: var(--primary-color); + background: rgba(46, 93, 49, 0.2); +} + +.device-icon { + width: 32px; + height: 32px; + margin: 0 auto var(--spacing-xs); + background-size: contain; +} + +.device-name { + font-size: var(--font-body); + color: var(--text-primary); + margin-bottom: var(--spacing-xs); +} + +.device-status { + font-size: var(--font-small); + color: var(--text-muted); +} +``` + +### 4. 功能按钮组 +```css +.function-buttons { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--spacing-sm); + margin-top: var(--spacing-md); +} + +.function-btn { + background: var(--primary-color); + color: var(--text-primary); + border: none; + border-radius: 4px; + padding: var(--spacing-sm) var(--spacing-md); + font-size: var(--font-body); + cursor: pointer; + transition: all 0.2s ease; + display: flex; + align-items: center; + justify-content: center; + gap: var(--spacing-xs); +} + +.function-btn:hover { + background: var(--primary-hover); +} + +.function-btn:active { + background: var(--primary-active); +} + +.function-btn:disabled { + background: var(--text-muted); + cursor: not-allowed; +} + +/* 不同类型按钮 */ +.function-btn.warning { + background: var(--warning-color); +} + +.function-btn.danger { + background: var(--danger-color); +} + +.function-btn.info { + background: var(--info-color); +} +``` + +### 5. 状态指示器 +```css +.status-indicator { + display: inline-block; + width: 8px; + height: 8px; + border-radius: 50%; + margin-right: var(--spacing-xs); +} + +.status-online { + background: var(--success-color); + box-shadow: 0 0 4px var(--success-color); +} + +.status-warning { + background: var(--warning-color); + animation: blink 1s infinite; +} + +.status-offline { + background: var(--text-muted); +} + +@keyframes blink { + 0%, 50% { opacity: 1; } + 51%, 100% { opacity: 0.3; } +} +``` + +### 6. 统计信息面板 +```css +.stats-panel { + background: var(--card-bg); + border-radius: 6px; + padding: var(--spacing-md); + margin-top: var(--spacing-md); +} + +.stat-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: var(--spacing-xs) 0; + border-bottom: 1px solid var(--border-color); +} + +.stat-item:last-child { + border-bottom: none; +} + +.stat-label { + font-size: var(--font-body); + color: var(--text-secondary); +} + +.stat-value { + font-size: var(--font-body); + font-weight: var(--font-weight-medium); + color: var(--text-primary); +} + +.stat-value.danger { + color: var(--danger-color); +} + +.stat-value.warning { + color: var(--warning-color); +} + +.stat-value.success { + color: var(--success-color); +} +``` + +## 模块具体设计 + +### 战场探索模块 +- **机器狗控制区域**:自主建图、导航避障功能按钮 +- **无人机控制区域**:照片传输、人物识别功能按钮 +- **状态显示**:设备在线状态、电池电量、信号强度 + +### 情报传输模块 +- **通话控制**:开始通话、结束通话、静音按钮 +- **频道设置**:频道选择、音量调节 +- **通话状态**:当前通话状态、通话时长 + +### 敌情统计模块 +- **统计信息**:已发现目标数量、威胁等级分布 +- **快速操作**:刷新数据、导出报告、AI分析 +- **可视化图表**:敌情分布图、时间趋势图 + +## 交互设计 + +### 状态反馈 +- **悬停效果**:按钮和卡片悬停时边框高亮 +- **点击反馈**:按钮点击时的缩放效果 +- **状态指示**:不同颜色表示不同的设备和功能状态 + +### 响应式考虑 +- **固定宽度**:320px,适合1920x1080及以上分辨率 +- **滚动支持**:内容超出时支持垂直滚动 +- **最小高度**:每个模块保持合适的最小高度 + +## 技术实现要点 + +### Qt实现建议 +- 使用`QWidget`作为主容器 +- 使用`QVBoxLayout`进行垂直布局 +- 使用`QGroupBox`或自定义`QFrame`实现模块卡片 +- 使用`QGridLayout`实现按钮网格布局 +- 使用QSS样式表实现视觉效果 + +### 信号槽设计 +```cpp +// 主要信号定义 +signals: + void startMapping(); // 开始建图 + void startNavigation(); // 开始导航 + void startPhotoTransmission(); // 开始照片传输 + void startPersonRecognition(); // 开始人物识别 + void startVoiceCall(); // 开始语音通话 + void refreshEnemyStats(); // 刷新敌情统计 + void requestAIAnalysis(); // 请求AI分析 +``` + +这个设计规范确保了界面的专业性、可用性和可扩展性,同时保持了军事应用的严肃性和实用性。 \ No newline at end of file diff --git a/src/Client/doc/ui_design/right_panel_implementation.cpp b/src/Client/doc/ui_design/right_panel_implementation.cpp new file mode 100644 index 0000000..bc5fb6c --- /dev/null +++ b/src/Client/doc/ui_design/right_panel_implementation.cpp @@ -0,0 +1,682 @@ +// RightFunctionPanel.h +#ifndef RIGHTFUNCTIONPANEL_H +#define RIGHTFUNCTIONPANEL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class ModuleCard : public QFrame +{ + Q_OBJECT + +public: + explicit ModuleCard(const QString &title, const QString &icon, QWidget *parent = nullptr); + void addContent(QWidget *content); + +private: + QVBoxLayout *m_contentLayout; + QLabel *m_titleLabel; +}; + +class DeviceCard : public QFrame +{ + Q_OBJECT + +public: + explicit DeviceCard(const QString &name, const QString &iconPath, QWidget *parent = nullptr); + void setStatus(const QString &status, const QColor &color); + void setActive(bool active); + +signals: + void deviceSelected(const QString &deviceName); + +protected: + void mousePressEvent(QMouseEvent *event) override; + void paintEvent(QPaintEvent *event) override; + +private: + QString m_deviceName; + QLabel *m_iconLabel; + QLabel *m_nameLabel; + QLabel *m_statusLabel; + bool m_isActive = false; +}; + +class RightFunctionPanel : public QWidget +{ + Q_OBJECT + +public: + explicit RightFunctionPanel(QWidget *parent = nullptr); + +signals: + // 战场探索信号 + void startMapping(); + void stopMapping(); + void startNavigation(); + void stopNavigation(); + void startPhotoTransmission(); + void stopPhotoTransmission(); + void startPersonRecognition(); + void stopPersonRecognition(); + + // 情报传输信号 + void startVoiceCall(); + void endVoiceCall(); + void muteCall(bool muted); + void setCallVolume(int volume); + + // 敌情统计信号 + void refreshEnemyStats(); + void exportReport(); + void requestAIAnalysis(); + +public slots: + void updateEnemyStats(int totalEnemies, const QString &threatLevel); + void updateDeviceStatus(const QString &deviceName, bool online, int battery); + +private slots: + void onDeviceSelected(const QString &deviceName); + void onMappingToggle(); + void onNavigationToggle(); + void onPhotoTransmissionToggle(); + void onPersonRecognitionToggle(); + void onVoiceCallToggle(); + void onRefreshStats(); + void onAIAnalysis(); + +private: + void setupUI(); + void setupBattlefieldExplorationModule(); + void setupIntelligenceModule(); + void setupEnemyStatsModule(); + void applyStyles(); + + // UI组件 + QVBoxLayout *m_mainLayout; + + // 战场探索模块 + ModuleCard *m_explorationCard; + DeviceCard *m_robotDogCard; + DeviceCard *m_droneCard; + QPushButton *m_mappingBtn; + QPushButton *m_navigationBtn; + QPushButton *m_photoBtn; + QPushButton *m_recognitionBtn; + QString m_selectedDevice; + + // 情报传输模块 + ModuleCard *m_intelligenceCard; + QPushButton *m_voiceCallBtn; + QPushButton *m_muteBtn; + QSlider *m_volumeSlider; + QLabel *m_callStatusLabel; + bool m_isInCall = false; + + // 敌情统计模块 + ModuleCard *m_statsCard; + QLabel *m_totalEnemiesLabel; + QLabel *m_threatLevelLabel; + QPushButton *m_refreshBtn; + QPushButton *m_aiAnalysisBtn; + QPushButton *m_exportBtn; +}; + +#endif // RIGHTFUNCTIONPANEL_H + +// RightFunctionPanel.cpp +#include "RightFunctionPanel.h" +#include +#include +#include + +// ModuleCard实现 +ModuleCard::ModuleCard(const QString &title, const QString &icon, QWidget *parent) + : QFrame(parent) +{ + setObjectName("ModuleCard"); + setFrameStyle(QFrame::StyledPanel); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setSpacing(12); + layout->setContentsMargins(12, 12, 12, 12); + + // 标题栏 + QHBoxLayout *headerLayout = new QHBoxLayout(); + QLabel *iconLabel = new QLabel(); + iconLabel->setObjectName("ModuleIcon"); + iconLabel->setText(icon); // 使用Unicode图标或设置图片 + iconLabel->setFixedSize(20, 20); + + m_titleLabel = new QLabel(title); + m_titleLabel->setObjectName("ModuleTitle"); + + headerLayout->addWidget(iconLabel); + headerLayout->addWidget(m_titleLabel); + headerLayout->addStretch(); + + layout->addLayout(headerLayout); + + // 内容区域 + m_contentLayout = new QVBoxLayout(); + m_contentLayout->setSpacing(8); + layout->addLayout(m_contentLayout); +} + +void ModuleCard::addContent(QWidget *content) +{ + m_contentLayout->addWidget(content); +} + +// DeviceCard实现 +DeviceCard::DeviceCard(const QString &name, const QString &iconPath, QWidget *parent) + : QFrame(parent), m_deviceName(name) +{ + setObjectName("DeviceCard"); + setFrameStyle(QFrame::StyledPanel); + setCursor(Qt::PointingHandCursor); + setFixedHeight(80); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setAlignment(Qt::AlignCenter); + layout->setSpacing(4); + + m_iconLabel = new QLabel(); + m_iconLabel->setObjectName("DeviceIcon"); + m_iconLabel->setFixedSize(32, 32); + m_iconLabel->setAlignment(Qt::AlignCenter); + // 设置图标,这里用文字代替 + m_iconLabel->setText(name.contains("机器狗") ? "🐕" : "🚁"); + + m_nameLabel = new QLabel(name); + m_nameLabel->setObjectName("DeviceName"); + m_nameLabel->setAlignment(Qt::AlignCenter); + + m_statusLabel = new QLabel("离线"); + m_statusLabel->setObjectName("DeviceStatus"); + m_statusLabel->setAlignment(Qt::AlignCenter); + + layout->addWidget(m_iconLabel); + layout->addWidget(m_nameLabel); + layout->addWidget(m_statusLabel); +} + +void DeviceCard::setStatus(const QString &status, const QColor &color) +{ + m_statusLabel->setText(status); + m_statusLabel->setStyleSheet(QString("color: %1;").arg(color.name())); +} + +void DeviceCard::setActive(bool active) +{ + m_isActive = active; + update(); +} + +void DeviceCard::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + emit deviceSelected(m_deviceName); + } + QFrame::mousePressEvent(event); +} + +void DeviceCard::paintEvent(QPaintEvent *event) +{ + QFrame::paintEvent(event); + + if (m_isActive) { + QPainter painter(this); + painter.setPen(QPen(QColor("#2E5D31"), 2)); + painter.drawRect(rect().adjusted(1, 1, -1, -1)); + } +} + +// RightFunctionPanel实现 +RightFunctionPanel::RightFunctionPanel(QWidget *parent) + : QWidget(parent) +{ + setupUI(); + applyStyles(); +} + +void RightFunctionPanel::setupUI() +{ + m_mainLayout = new QVBoxLayout(this); + m_mainLayout->setSpacing(12); + m_mainLayout->setContentsMargins(16, 16, 16, 16); + + // 面板标题 + QLabel *titleLabel = new QLabel("功能面板"); + titleLabel->setObjectName("PanelTitle"); + titleLabel->setAlignment(Qt::AlignCenter); + m_mainLayout->addWidget(titleLabel); + + setupBattlefieldExplorationModule(); + setupIntelligenceModule(); + setupEnemyStatsModule(); + + m_mainLayout->addStretch(); +} + +void RightFunctionPanel::setupBattlefieldExplorationModule() +{ + m_explorationCard = new ModuleCard("战场探索", "🔍", this); + + // 设备选择 + QHBoxLayout *deviceLayout = new QHBoxLayout(); + m_robotDogCard = new DeviceCard("机器狗", "robot_dog.png", this); + m_droneCard = new DeviceCard("无人机", "drone.png", this); + + connect(m_robotDogCard, &DeviceCard::deviceSelected, this, &RightFunctionPanel::onDeviceSelected); + connect(m_droneCard, &DeviceCard::deviceSelected, this, &RightFunctionPanel::onDeviceSelected); + + deviceLayout->addWidget(m_robotDogCard); + deviceLayout->addWidget(m_droneCard); + + QWidget *deviceWidget = new QWidget(); + deviceWidget->setLayout(deviceLayout); + m_explorationCard->addContent(deviceWidget); + + // 功能按钮 + QGridLayout *buttonLayout = new QGridLayout(); + m_mappingBtn = new QPushButton("自主建图"); + m_navigationBtn = new QPushButton("导航避障"); + m_photoBtn = new QPushButton("照片传输"); + m_recognitionBtn = new QPushButton("人物识别"); + + // 设置按钮样式类名 + m_mappingBtn->setObjectName("FunctionBtn"); + m_navigationBtn->setObjectName("FunctionBtn"); + m_photoBtn->setObjectName("FunctionBtn"); + m_recognitionBtn->setObjectName("FunctionBtn"); + + buttonLayout->addWidget(m_mappingBtn, 0, 0); + buttonLayout->addWidget(m_navigationBtn, 0, 1); + buttonLayout->addWidget(m_photoBtn, 1, 0); + buttonLayout->addWidget(m_recognitionBtn, 1, 1); + + connect(m_mappingBtn, &QPushButton::clicked, this, &RightFunctionPanel::onMappingToggle); + connect(m_navigationBtn, &QPushButton::clicked, this, &RightFunctionPanel::onNavigationToggle); + connect(m_photoBtn, &QPushButton::clicked, this, &RightFunctionPanel::onPhotoTransmissionToggle); + connect(m_recognitionBtn, &QPushButton::clicked, this, &RightFunctionPanel::onPersonRecognitionToggle); + + QWidget *buttonWidget = new QWidget(); + buttonWidget->setLayout(buttonLayout); + m_explorationCard->addContent(buttonWidget); + + m_mainLayout->addWidget(m_explorationCard); +} + +void RightFunctionPanel::setupIntelligenceModule() +{ + m_intelligenceCard = new ModuleCard("情报传输", "📡", this); + + // 通话控制 + QHBoxLayout *callLayout = new QHBoxLayout(); + m_voiceCallBtn = new QPushButton("开始通话"); + m_muteBtn = new QPushButton("静音"); + m_voiceCallBtn->setObjectName("FunctionBtn"); + m_muteBtn->setObjectName("FunctionBtn"); + m_muteBtn->setEnabled(false); + + callLayout->addWidget(m_voiceCallBtn); + callLayout->addWidget(m_muteBtn); + + connect(m_voiceCallBtn, &QPushButton::clicked, this, &RightFunctionPanel::onVoiceCallToggle); + + QWidget *callWidget = new QWidget(); + callWidget->setLayout(callLayout); + m_intelligenceCard->addContent(callWidget); + + // 音量控制 + QHBoxLayout *volumeLayout = new QHBoxLayout(); + QLabel *volumeLabel = new QLabel("音量:"); + m_volumeSlider = new QSlider(Qt::Horizontal); + m_volumeSlider->setRange(0, 100); + m_volumeSlider->setValue(70); + + volumeLayout->addWidget(volumeLabel); + volumeLayout->addWidget(m_volumeSlider); + + QWidget *volumeWidget = new QWidget(); + volumeWidget->setLayout(volumeLayout); + m_intelligenceCard->addContent(volumeWidget); + + // 通话状态 + m_callStatusLabel = new QLabel("未连接"); + m_callStatusLabel->setObjectName("CallStatus"); + m_intelligenceCard->addContent(m_callStatusLabel); + + m_mainLayout->addWidget(m_intelligenceCard); +} + +void RightFunctionPanel::setupEnemyStatsModule() +{ + m_statsCard = new ModuleCard("敌情统计", "📊", this); + + // 统计信息 + QVBoxLayout *statsLayout = new QVBoxLayout(); + + m_totalEnemiesLabel = new QLabel("已发现目标: 0"); + m_threatLevelLabel = new QLabel("威胁等级: 无"); + m_totalEnemiesLabel->setObjectName("StatLabel"); + m_threatLevelLabel->setObjectName("StatLabel"); + + statsLayout->addWidget(m_totalEnemiesLabel); + statsLayout->addWidget(m_threatLevelLabel); + + QWidget *statsWidget = new QWidget(); + statsWidget->setLayout(statsLayout); + m_statsCard->addContent(statsWidget); + + // 操作按钮 + QHBoxLayout *statsButtonLayout = new QHBoxLayout(); + m_refreshBtn = new QPushButton("刷新"); + m_aiAnalysisBtn = new QPushButton("AI分析"); + m_exportBtn = new QPushButton("导出报告"); + + m_refreshBtn->setObjectName("FunctionBtn"); + m_aiAnalysisBtn->setObjectName("FunctionBtn"); + m_exportBtn->setObjectName("FunctionBtn"); + + statsButtonLayout->addWidget(m_refreshBtn); + statsButtonLayout->addWidget(m_aiAnalysisBtn); + + connect(m_refreshBtn, &QPushButton::clicked, this, &RightFunctionPanel::onRefreshStats); + connect(m_aiAnalysisBtn, &QPushButton::clicked, this, &RightFunctionPanel::onAIAnalysis); + + QWidget *statsButtonWidget = new QWidget(); + statsButtonWidget->setLayout(statsButtonLayout); + m_statsCard->addContent(statsButtonWidget); + + // 导出按钮单独一行 + m_statsCard->addContent(m_exportBtn); + + m_mainLayout->addWidget(m_statsCard); +} + +void RightFunctionPanel::applyStyles() +{ + QString styles = R"( + QWidget { + font-family: "Microsoft YaHei", "SimHei", sans-serif; + } + + RightFunctionPanel { + background-color: #2A3F47; + border-left: 2px solid #546E7A; + } + + #PanelTitle { + font-size: 16px; + font-weight: bold; + color: #FFFFFF; + border-bottom: 1px solid #546E7A; + padding-bottom: 8px; + margin-bottom: 12px; + } + + #ModuleCard { + background-color: #354A54; + border: 1px solid #546E7A; + border-radius: 8px; + padding: 12px; + } + + #ModuleCard:hover { + border-color: #2E5D31; + background-color: #4A6572; + } + + #ModuleTitle { + font-size: 14px; + font-weight: 500; + color: #FFFFFF; + } + + #ModuleIcon { + font-size: 16px; + color: #2E5D31; + } + + #DeviceCard { + background-color: #3D525E; + border: 1px solid #546E7A; + border-radius: 6px; + padding: 8px; + } + + #DeviceCard:hover { + background-color: #4A6572; + border-color: #2E5D31; + } + + #DeviceName { + font-size: 12px; + color: #FFFFFF; + font-weight: 500; + } + + #DeviceStatus { + font-size: 10px; + color: #78909C; + } + + #FunctionBtn { + background-color: #2E5D31; + color: #FFFFFF; + border: none; + border-radius: 4px; + padding: 8px 12px; + font-size: 12px; + font-weight: 500; + min-height: 32px; + } + + #FunctionBtn:hover { + background-color: #245429; + } + + #FunctionBtn:pressed { + background-color: #1a3d1d; + } + + #FunctionBtn:disabled { + background-color: #78909C; + } + + #StatLabel { + font-size: 12px; + color: #B0BEC5; + padding: 4px 0; + } + + #CallStatus { + font-size: 11px; + color: #78909C; + font-style: italic; + text-align: center; + } + + QSlider::groove:horizontal { + border: 1px solid #546E7A; + height: 4px; + background: #3D525E; + border-radius: 2px; + } + + QSlider::handle:horizontal { + background: #2E5D31; + border: 1px solid #546E7A; + width: 12px; + margin: -4px 0; + border-radius: 6px; + } + + QSlider::handle:horizontal:hover { + background: #245429; + } + )"; + + setStyleSheet(styles); +} + +// 槽函数实现 +void RightFunctionPanel::onDeviceSelected(const QString &deviceName) +{ + m_selectedDevice = deviceName; + + // 更新设备选择状态 + m_robotDogCard->setActive(deviceName.contains("机器狗")); + m_droneCard->setActive(deviceName.contains("无人机")); + + // 根据设备类型启用/禁用相应按钮 + bool isRobotDog = deviceName.contains("机器狗"); + m_mappingBtn->setEnabled(isRobotDog); + m_navigationBtn->setEnabled(isRobotDog); + m_photoBtn->setEnabled(!isRobotDog); + m_recognitionBtn->setEnabled(!isRobotDog); +} + +void RightFunctionPanel::onMappingToggle() +{ + static bool isMappingActive = false; + isMappingActive = !isMappingActive; + + m_mappingBtn->setText(isMappingActive ? "停止建图" : "自主建图"); + + if (isMappingActive) { + emit startMapping(); + } else { + emit stopMapping(); + } +} + +void RightFunctionPanel::onNavigationToggle() +{ + static bool isNavigationActive = false; + isNavigationActive = !isNavigationActive; + + m_navigationBtn->setText(isNavigationActive ? "停止导航" : "导航避障"); + + if (isNavigationActive) { + emit startNavigation(); + } else { + emit stopNavigation(); + } +} + +void RightFunctionPanel::onPhotoTransmissionToggle() +{ + static bool isTransmissionActive = false; + isTransmissionActive = !isTransmissionActive; + + m_photoBtn->setText(isTransmissionActive ? "停止传输" : "照片传输"); + + if (isTransmissionActive) { + emit startPhotoTransmission(); + } else { + emit stopPhotoTransmission(); + } +} + +void RightFunctionPanel::onPersonRecognitionToggle() +{ + static bool isRecognitionActive = false; + isRecognitionActive = !isRecognitionActive; + + m_recognitionBtn->setText(isRecognitionActive ? "停止识别" : "人物识别"); + + if (isRecognitionActive) { + emit startPersonRecognition(); + } else { + emit stopPersonRecognition(); + } +} + +void RightFunctionPanel::onVoiceCallToggle() +{ + m_isInCall = !m_isInCall; + + m_voiceCallBtn->setText(m_isInCall ? "结束通话" : "开始通话"); + m_muteBtn->setEnabled(m_isInCall); + m_callStatusLabel->setText(m_isInCall ? "通话中..." : "未连接"); + + if (m_isInCall) { + emit startVoiceCall(); + } else { + emit endVoiceCall(); + } +} + +void RightFunctionPanel::onRefreshStats() +{ + emit refreshEnemyStats(); + + // 模拟刷新效果 + m_refreshBtn->setText("刷新中..."); + m_refreshBtn->setEnabled(false); + + QTimer::singleShot(2000, [this]() { + m_refreshBtn->setText("刷新"); + m_refreshBtn->setEnabled(true); + }); +} + +void RightFunctionPanel::onAIAnalysis() +{ + emit requestAIAnalysis(); + + // 显示分析状态 + m_aiAnalysisBtn->setText("分析中..."); + m_aiAnalysisBtn->setEnabled(false); + + QTimer::singleShot(3000, [this]() { + m_aiAnalysisBtn->setText("AI分析"); + m_aiAnalysisBtn->setEnabled(true); + }); +} + +void RightFunctionPanel::updateEnemyStats(int totalEnemies, const QString &threatLevel) +{ + m_totalEnemiesLabel->setText(QString("已发现目标: %1").arg(totalEnemies)); + m_threatLevelLabel->setText(QString("威胁等级: %1").arg(threatLevel)); + + // 根据威胁等级设置颜色 + if (threatLevel == "高") { + m_threatLevelLabel->setStyleSheet("color: #DC143C;"); + } else if (threatLevel == "中") { + m_threatLevelLabel->setStyleSheet("color: #FF8C00;"); + } else { + m_threatLevelLabel->setStyleSheet("color: #4CAF50;"); + } +} + +void RightFunctionPanel::updateDeviceStatus(const QString &deviceName, bool online, int battery) +{ + DeviceCard *deviceCard = nullptr; + if (deviceName.contains("机器狗")) { + deviceCard = m_robotDogCard; + } else if (deviceName.contains("无人机")) { + deviceCard = m_droneCard; + } + + if (deviceCard) { + if (online) { + deviceCard->setStatus(QString("在线 %1%").arg(battery), QColor("#4CAF50")); + } else { + deviceCard->setStatus("离线", QColor("#78909C")); + } + } +} + +#include "RightFunctionPanel.moc" \ No newline at end of file diff --git a/src/Client/include/ui/components/RightFunctionPanel.h b/src/Client/include/ui/components/RightFunctionPanel.h new file mode 100644 index 0000000..0d6cff6 --- /dev/null +++ b/src/Client/include/ui/components/RightFunctionPanel.h @@ -0,0 +1,333 @@ +/** + * @file RightFunctionPanel.h + * @brief 右侧功能面板组件定义 + * @author BattlefieldExplorationSystem Team + * @date 2024-01-15 + * @version 1.0 + * + * 右侧功能面板,提供战场探索系统的核心功能控制,包括: + * - 战场探索模块(机器狗和无人机控制) + * - 情报传输模块(语音通话功能) + * - 敌情统计模块(敌情可视化和AI分析) + * + * @note 依赖Qt GUI模块 + * @since 1.0 + */ + +#ifndef RIGHTFUNCTIONPANEL_H +#define RIGHTFUNCTIONPANEL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @class ModuleCard + * @brief 功能模块卡片组件 + * + * 用于显示单个功能模块的卡片容器,包含标题和内容区域 + */ +class ModuleCard : public QFrame +{ + Q_OBJECT + +public: + /** + * @brief 构造函数 + * @param title 模块标题 + * @param icon 模块图标(Unicode字符或图片路径) + * @param parent 父组件指针 + */ + explicit ModuleCard(const QString &title, const QString &icon, QWidget *parent = nullptr); + + /** + * @brief 添加内容到模块卡片 + * @param content 要添加的内容组件 + */ + void addContent(QWidget *content); + +private: + QVBoxLayout *m_contentLayout; ///< 内容区域布局 + QLabel *m_titleLabel; ///< 标题标签 +}; + +/** + * @class RightDeviceCard + * @brief 右侧面板设备卡片组件 + * + * 用于显示单个设备的信息卡片,支持点击选择和状态显示 + */ +class RightDeviceCard : public QFrame +{ + Q_OBJECT + +public: + /** + * @brief 构造函数 + * @param name 设备名称 + * @param iconPath 设备图标路径 + * @param parent 父组件指针 + */ + explicit RightDeviceCard(const QString &name, const QString &iconPath, QWidget *parent = nullptr); + + /** + * @brief 设置设备状态 + * @param status 状态文本 + * @param color 状态颜色 + */ + void setStatus(const QString &status, const QColor &color); + + /** + * @brief 设置设备选中状态 + * @param active 是否选中 + */ + void setActive(bool active); + +signals: + /** + * @brief 设备被选中信号 + * @param deviceName 设备名称 + */ + void deviceSelected(const QString &deviceName); + +protected: + /** + * @brief 鼠标点击事件 + * @param event 鼠标事件 + */ + void mousePressEvent(QMouseEvent *event) override; + + /** + * @brief 绘制事件(绘制选中边框) + * @param event 绘制事件 + */ + void paintEvent(QPaintEvent *event) override; + +private: + QString m_deviceName; ///< 设备名称 + QLabel *m_iconLabel; ///< 图标标签 + QLabel *m_nameLabel; ///< 名称标签 + QLabel *m_statusLabel; ///< 状态标签 + bool m_isActive = false; ///< 是否选中状态 +}; + +/** + * @class RightFunctionPanel + * @brief 右侧功能面板主组件 + * + * 包含战场探索、情报传输、敌情统计三大功能模块的主面板 + */ +class RightFunctionPanel : public QWidget +{ + Q_OBJECT + +public: + /** + * @brief 构造函数 + * @param parent 父组件指针 + */ + explicit RightFunctionPanel(QWidget *parent = nullptr); + +signals: + // 战场探索模块信号 + /** + * @brief 开始自主建图信号 + */ + void startMapping(); + + /** + * @brief 停止自主建图信号 + */ + void stopMapping(); + + /** + * @brief 开始导航避障信号 + */ + void startNavigation(); + + /** + * @brief 停止导航避障信号 + */ + void stopNavigation(); + + /** + * @brief 开始照片传输信号 + */ + void startPhotoTransmission(); + + /** + * @brief 停止照片传输信号 + */ + void stopPhotoTransmission(); + + /** + * @brief 开始人物识别信号 + */ + void startPersonRecognition(); + + /** + * @brief 停止人物识别信号 + */ + void stopPersonRecognition(); + + // 情报传输模块信号 + /** + * @brief 开始语音通话信号 + */ + void startVoiceCall(); + + /** + * @brief 结束语音通话信号 + */ + void endVoiceCall(); + + /** + * @brief 通话静音切换信号 + * @param muted 是否静音 + */ + void muteCall(bool muted); + + /** + * @brief 设置通话音量信号 + * @param volume 音量值(0-100) + */ + void setCallVolume(int volume); + + // 敌情统计模块信号 + /** + * @brief 刷新敌情统计信号 + */ + void refreshEnemyStats(); + + /** + * @brief 导出报告信号 + */ + void exportReport(); + + /** + * @brief 请求AI分析信号 + */ + void requestAIAnalysis(); + +public slots: + /** + * @brief 更新敌情统计信息 + * @param totalEnemies 敌人总数 + * @param threatLevel 威胁等级 + */ + void updateEnemyStats(int totalEnemies, const QString &threatLevel); + + /** + * @brief 更新设备状态 + * @param deviceName 设备名称 + * @param online 是否在线 + * @param battery 电池电量 + */ + void updateDeviceStatus(const QString &deviceName, bool online, int battery); + +private slots: + /** + * @brief 设备选择槽函数 + * @param deviceName 设备名称 + */ + void onDeviceSelected(const QString &deviceName); + + /** + * @brief 自主建图开关槽函数 + */ + void onMappingToggle(); + + /** + * @brief 导航避障开关槽函数 + */ + void onNavigationToggle(); + + /** + * @brief 照片传输开关槽函数 + */ + void onPhotoTransmissionToggle(); + + /** + * @brief 人物识别开关槽函数 + */ + void onPersonRecognitionToggle(); + + /** + * @brief 语音通话开关槽函数 + */ + void onVoiceCallToggle(); + + /** + * @brief 刷新统计槽函数 + */ + void onRefreshStats(); + + /** + * @brief AI分析槽函数 + */ + void onAIAnalysis(); + +private: + /** + * @brief 设置UI界面 + */ + void setupUI(); + + /** + * @brief 设置战场探索模块 + */ + void setupBattlefieldExplorationModule(); + + /** + * @brief 设置情报传输模块 + */ + void setupIntelligenceModule(); + + /** + * @brief 设置敌情统计模块 + */ + void setupEnemyStatsModule(); + + /** + * @brief 应用样式表 + */ + void applyStyles(); + + // UI组件 + QVBoxLayout *m_mainLayout; ///< 主布局 + + // 战场探索模块 + ModuleCard *m_explorationCard; ///< 探索模块卡片 + RightDeviceCard *m_robotDogCard; ///< 机器狗设备卡片 + RightDeviceCard *m_droneCard; ///< 无人机设备卡片 + QPushButton *m_mappingBtn; ///< 建图按钮 + QPushButton *m_navigationBtn; ///< 导航按钮 + QPushButton *m_photoBtn; ///< 照片传输按钮 + QPushButton *m_recognitionBtn; ///< 人物识别按钮 + QString m_selectedDevice; ///< 当前选择的设备 + + // 情报传输模块 + ModuleCard *m_intelligenceCard; ///< 情报模块卡片 + QPushButton *m_voiceCallBtn; ///< 语音通话按钮 + QPushButton *m_muteBtn; ///< 静音按钮 + QSlider *m_volumeSlider; ///< 音量滑块 + QLabel *m_callStatusLabel; ///< 通话状态标签 + bool m_isInCall = false; ///< 是否在通话中 + + // 敌情统计模块 + ModuleCard *m_statsCard; ///< 统计模块卡片 + QLabel *m_totalEnemiesLabel; ///< 敌人总数标签 + QLabel *m_threatLevelLabel; ///< 威胁等级标签 + QPushButton *m_refreshBtn; ///< 刷新按钮 + QPushButton *m_aiAnalysisBtn; ///< AI分析按钮 + QPushButton *m_exportBtn; ///< 导出按钮 +}; + +#endif // RIGHTFUNCTIONPANEL_H \ No newline at end of file diff --git a/src/Client/include/ui/main/MainWindow.h b/src/Client/include/ui/main/MainWindow.h index f226443..eb5f8f3 100644 --- a/src/Client/include/ui/main/MainWindow.h +++ b/src/Client/include/ui/main/MainWindow.h @@ -42,6 +42,7 @@ // #include "AudioModule/IntelligenceUI.h" // 暂时注释掉,待实现 #include "ui/components/DeviceListPanel.h" #include "ui/components/SystemLogPanel.h" +#include "ui/components/RightFunctionPanel.h" // 标准库头文件 #include @@ -221,6 +222,73 @@ private slots: */ void onAddDeviceRequested(const QString &deviceType); +private slots: + // 右侧功能面板信号处理槽函数 + /** + * @brief 开始自主建图槽函数 + */ + void onStartMapping(); + + /** + * @brief 停止自主建图槽函数 + */ + void onStopMapping(); + + /** + * @brief 开始导航避障槽函数 + */ + void onStartNavigation(); + + /** + * @brief 停止导航避障槽函数 + */ + void onStopNavigation(); + + /** + * @brief 开始照片传输槽函数 + */ + void onStartPhotoTransmission(); + + /** + * @brief 停止照片传输槽函数 + */ + void onStopPhotoTransmission(); + + /** + * @brief 开始人物识别槽函数 + */ + void onStartPersonRecognition(); + + /** + * @brief 停止人物识别槽函数 + */ + void onStopPersonRecognition(); + + /** + * @brief 开始语音通话槽函数 + */ + void onStartVoiceCall(); + + /** + * @brief 结束语音通话槽函数 + */ + void onEndVoiceCall(); + + /** + * @brief 刷新敌情统计槽函数 + */ + void onRefreshEnemyStats(); + + /** + * @brief 请求AI分析槽函数 + */ + void onRequestAIAnalysis(); + + /** + * @brief 导出报告槽函数 + */ + void onExportReport(); + private: /** * @brief 初始化UI界面 @@ -237,6 +305,11 @@ private: */ void setupSystemLogPanel(); + /** + * @brief 设置右侧功能面板 + */ + void setupRightFunctionPanel(); + /** * @brief 连接信号和槽 */ @@ -257,6 +330,7 @@ private: // IntelligenceUI *m_intelligenceUI; ///< 情报传达界面指针(暂时注释掉) DeviceListPanel *m_deviceListPanel; ///< 设备列表面板组件 SystemLogPanel *m_systemLogPanel; ///< 系统日志面板组件 + RightFunctionPanel *m_rightFunctionPanel; ///< 右侧功能面板组件 QSplitter *m_leftPanelSplitter; ///< 左侧面板分割器 QVector> m_robotList; ///< 机器人列表(名称-IP地址对) QVector> m_uavList; ///< 无人机列表(名称-IP地址对) diff --git a/src/Client/src/ui/components/RightFunctionPanel.cpp b/src/Client/src/ui/components/RightFunctionPanel.cpp new file mode 100644 index 0000000..4a4c68f --- /dev/null +++ b/src/Client/src/ui/components/RightFunctionPanel.cpp @@ -0,0 +1,631 @@ +/** + * @file RightFunctionPanel.cpp + * @brief 右侧功能面板组件实现 + * @author BattlefieldExplorationSystem Team + * @date 2024-01-15 + * @version 1.0 + */ + +#include "ui/components/RightFunctionPanel.h" +#include +#include +#include + +// ModuleCard实现 +ModuleCard::ModuleCard(const QString &title, const QString &icon, QWidget *parent) + : QFrame(parent) +{ + setObjectName("ModuleCard"); + setFrameStyle(QFrame::StyledPanel); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setSpacing(12); + layout->setContentsMargins(12, 12, 12, 12); + + // 标题栏 + QHBoxLayout *headerLayout = new QHBoxLayout(); + QLabel *iconLabel = new QLabel(); + iconLabel->setObjectName("ModuleIcon"); + iconLabel->setText(icon); // 使用Unicode图标 + iconLabel->setFixedSize(20, 20); + + m_titleLabel = new QLabel(title); + m_titleLabel->setObjectName("ModuleTitle"); + + headerLayout->addWidget(iconLabel); + headerLayout->addWidget(m_titleLabel); + headerLayout->addStretch(); + + layout->addLayout(headerLayout); + + // 内容区域 + m_contentLayout = new QVBoxLayout(); + m_contentLayout->setSpacing(8); + layout->addLayout(m_contentLayout); +} + +void ModuleCard::addContent(QWidget *content) +{ + m_contentLayout->addWidget(content); +} + +// RightDeviceCard实现 +RightDeviceCard::RightDeviceCard(const QString &name, const QString &iconPath, QWidget *parent) + : QFrame(parent), m_deviceName(name) +{ + setObjectName("RightDeviceCard"); + setFrameStyle(QFrame::StyledPanel); + setCursor(Qt::PointingHandCursor); + setFixedHeight(80); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setAlignment(Qt::AlignCenter); + layout->setSpacing(4); + + m_iconLabel = new QLabel(); + m_iconLabel->setObjectName("DeviceIcon"); + m_iconLabel->setFixedSize(32, 32); + m_iconLabel->setAlignment(Qt::AlignCenter); + + // 设置图标,根据设备类型使用不同的Unicode字符 + if (name.contains("机器狗") || name.contains("robot") || name.contains("dog")) { + m_iconLabel->setText("🐕"); + m_iconLabel->setStyleSheet("font-size: 24px;"); + } else if (name.contains("无人机") || name.contains("drone") || name.contains("uav")) { + m_iconLabel->setText("🚁"); + m_iconLabel->setStyleSheet("font-size: 24px;"); + } else { + m_iconLabel->setText("📡"); + m_iconLabel->setStyleSheet("font-size: 24px;"); + } + + m_nameLabel = new QLabel(name); + m_nameLabel->setObjectName("DeviceName"); + m_nameLabel->setAlignment(Qt::AlignCenter); + + m_statusLabel = new QLabel("离线"); + m_statusLabel->setObjectName("DeviceStatus"); + m_statusLabel->setAlignment(Qt::AlignCenter); + + layout->addWidget(m_iconLabel); + layout->addWidget(m_nameLabel); + layout->addWidget(m_statusLabel); +} + +void RightDeviceCard::setStatus(const QString &status, const QColor &color) +{ + m_statusLabel->setText(status); + m_statusLabel->setStyleSheet(QString("color: %1;").arg(color.name())); +} + +void RightDeviceCard::setActive(bool active) +{ + m_isActive = active; + update(); +} + +void RightDeviceCard::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + emit deviceSelected(m_deviceName); + } + QFrame::mousePressEvent(event); +} + +void RightDeviceCard::paintEvent(QPaintEvent *event) +{ + QFrame::paintEvent(event); + + if (m_isActive) { + QPainter painter(this); + painter.setPen(QPen(QColor("#2E5D31"), 2)); + painter.drawRect(rect().adjusted(1, 1, -1, -1)); + } +} + +// RightFunctionPanel实现 +RightFunctionPanel::RightFunctionPanel(QWidget *parent) + : QWidget(parent) +{ + setupUI(); + applyStyles(); +} + +void RightFunctionPanel::setupUI() +{ + setFixedWidth(320); + + m_mainLayout = new QVBoxLayout(this); + m_mainLayout->setSpacing(12); + m_mainLayout->setContentsMargins(16, 16, 16, 16); + + // 面板标题 + QLabel *titleLabel = new QLabel("功能面板"); + titleLabel->setObjectName("PanelTitle"); + titleLabel->setAlignment(Qt::AlignCenter); + m_mainLayout->addWidget(titleLabel); + + setupBattlefieldExplorationModule(); + setupIntelligenceModule(); + setupEnemyStatsModule(); + + m_mainLayout->addStretch(); +} + +void RightFunctionPanel::setupBattlefieldExplorationModule() +{ + m_explorationCard = new ModuleCard("战场探索", "🔍", this); + + // 设备选择 + QHBoxLayout *deviceLayout = new QHBoxLayout(); + m_robotDogCard = new RightDeviceCard("机器狗", "", this); + m_droneCard = new RightDeviceCard("无人机", "", this); + + connect(m_robotDogCard, &RightDeviceCard::deviceSelected, this, &RightFunctionPanel::onDeviceSelected); + connect(m_droneCard, &RightDeviceCard::deviceSelected, this, &RightFunctionPanel::onDeviceSelected); + + deviceLayout->addWidget(m_robotDogCard); + deviceLayout->addWidget(m_droneCard); + + QWidget *deviceWidget = new QWidget(); + deviceWidget->setLayout(deviceLayout); + m_explorationCard->addContent(deviceWidget); + + // 功能按钮 + QGridLayout *buttonLayout = new QGridLayout(); + m_mappingBtn = new QPushButton("自主建图"); + m_navigationBtn = new QPushButton("导航避障"); + m_photoBtn = new QPushButton("照片传输"); + m_recognitionBtn = new QPushButton("人物识别"); + + // 设置按钮样式类名 + m_mappingBtn->setObjectName("FunctionBtn"); + m_navigationBtn->setObjectName("FunctionBtn"); + m_photoBtn->setObjectName("FunctionBtn"); + m_recognitionBtn->setObjectName("FunctionBtn"); + + // 初始状态:禁用所有按钮,等待设备选择 + m_mappingBtn->setEnabled(false); + m_navigationBtn->setEnabled(false); + m_photoBtn->setEnabled(false); + m_recognitionBtn->setEnabled(false); + + buttonLayout->addWidget(m_mappingBtn, 0, 0); + buttonLayout->addWidget(m_navigationBtn, 0, 1); + buttonLayout->addWidget(m_photoBtn, 1, 0); + buttonLayout->addWidget(m_recognitionBtn, 1, 1); + + connect(m_mappingBtn, &QPushButton::clicked, this, &RightFunctionPanel::onMappingToggle); + connect(m_navigationBtn, &QPushButton::clicked, this, &RightFunctionPanel::onNavigationToggle); + connect(m_photoBtn, &QPushButton::clicked, this, &RightFunctionPanel::onPhotoTransmissionToggle); + connect(m_recognitionBtn, &QPushButton::clicked, this, &RightFunctionPanel::onPersonRecognitionToggle); + + QWidget *buttonWidget = new QWidget(); + buttonWidget->setLayout(buttonLayout); + m_explorationCard->addContent(buttonWidget); + + m_mainLayout->addWidget(m_explorationCard); +} + +void RightFunctionPanel::setupIntelligenceModule() +{ + m_intelligenceCard = new ModuleCard("情报传输", "📡", this); + + // 通话控制 + QHBoxLayout *callLayout = new QHBoxLayout(); + m_voiceCallBtn = new QPushButton("开始通话"); + m_muteBtn = new QPushButton("静音"); + m_voiceCallBtn->setObjectName("FunctionBtn"); + m_muteBtn->setObjectName("FunctionBtn"); + m_muteBtn->setEnabled(false); + + callLayout->addWidget(m_voiceCallBtn); + callLayout->addWidget(m_muteBtn); + + connect(m_voiceCallBtn, &QPushButton::clicked, this, &RightFunctionPanel::onVoiceCallToggle); + + QWidget *callWidget = new QWidget(); + callWidget->setLayout(callLayout); + m_intelligenceCard->addContent(callWidget); + + // 音量控制 + QHBoxLayout *volumeLayout = new QHBoxLayout(); + QLabel *volumeLabel = new QLabel("音量:"); + volumeLabel->setObjectName("VolumeLabel"); + m_volumeSlider = new QSlider(Qt::Horizontal); + m_volumeSlider->setRange(0, 100); + m_volumeSlider->setValue(70); + + volumeLayout->addWidget(volumeLabel); + volumeLayout->addWidget(m_volumeSlider); + + QWidget *volumeWidget = new QWidget(); + volumeWidget->setLayout(volumeLayout); + m_intelligenceCard->addContent(volumeWidget); + + // 通话状态 + m_callStatusLabel = new QLabel("未连接"); + m_callStatusLabel->setObjectName("CallStatus"); + m_callStatusLabel->setAlignment(Qt::AlignCenter); + m_intelligenceCard->addContent(m_callStatusLabel); + + m_mainLayout->addWidget(m_intelligenceCard); +} + +void RightFunctionPanel::setupEnemyStatsModule() +{ + m_statsCard = new ModuleCard("敌情统计", "📊", this); + + // 统计信息 + QVBoxLayout *statsLayout = new QVBoxLayout(); + + m_totalEnemiesLabel = new QLabel("已发现目标: 0"); + m_threatLevelLabel = new QLabel("威胁等级: 无"); + m_totalEnemiesLabel->setObjectName("StatLabel"); + m_threatLevelLabel->setObjectName("StatLabel"); + + statsLayout->addWidget(m_totalEnemiesLabel); + statsLayout->addWidget(m_threatLevelLabel); + + QWidget *statsWidget = new QWidget(); + statsWidget->setLayout(statsLayout); + m_statsCard->addContent(statsWidget); + + // 操作按钮 + QHBoxLayout *statsButtonLayout = new QHBoxLayout(); + m_refreshBtn = new QPushButton("刷新"); + m_aiAnalysisBtn = new QPushButton("AI分析"); + + m_refreshBtn->setObjectName("FunctionBtn"); + m_aiAnalysisBtn->setObjectName("FunctionBtn"); + + statsButtonLayout->addWidget(m_refreshBtn); + statsButtonLayout->addWidget(m_aiAnalysisBtn); + + connect(m_refreshBtn, &QPushButton::clicked, this, &RightFunctionPanel::onRefreshStats); + connect(m_aiAnalysisBtn, &QPushButton::clicked, this, &RightFunctionPanel::onAIAnalysis); + + QWidget *statsButtonWidget = new QWidget(); + statsButtonWidget->setLayout(statsButtonLayout); + m_statsCard->addContent(statsButtonWidget); + + // 导出按钮单独一行 + m_exportBtn = new QPushButton("导出报告"); + m_exportBtn->setObjectName("FunctionBtn"); + connect(m_exportBtn, &QPushButton::clicked, this, &RightFunctionPanel::exportReport); + m_statsCard->addContent(m_exportBtn); + + m_mainLayout->addWidget(m_statsCard); +} + +void RightFunctionPanel::applyStyles() +{ + QString styles = R"( + QWidget { + font-family: "Microsoft YaHei", "SimHei", sans-serif; + } + + RightFunctionPanel { + background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, + stop:0 rgb(15, 22, 32), stop:1 rgb(25, 35, 45)); + border-radius: 8px; + margin: 0px; + } + + #PanelTitle { + font-size: 18px; + font-weight: bold; + color: #FFFFFF; + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 rgba(82, 194, 242, 0.2), + stop:1 rgba(45, 120, 180, 0.2)); + border: 1px solid rgba(82, 194, 242, 0.5); + border-radius: 8px; + padding: 12px; + margin-bottom: 16px; + } + + #ModuleCard { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 rgba(30, 45, 55, 0.8), + stop:1 rgba(40, 58, 70, 0.8)); + border: 1px solid rgba(82, 194, 242, 0.3); + border-radius: 12px; + padding: 16px; + margin-bottom: 12px; + } + + #ModuleCard:hover { + border: 1px solid rgba(82, 194, 242, 0.6); + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 rgba(35, 52, 62, 0.9), + stop:1 rgba(45, 65, 78, 0.9)); + } + + #ModuleTitle { + font-size: 14px; + font-weight: 500; + color: #FFFFFF; + } + + #ModuleIcon { + font-size: 18px; + color: rgba(82, 194, 242, 0.8); + } + + #RightDeviceCard { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 rgba(25, 38, 48, 0.8), + stop:1 rgba(35, 50, 62, 0.8)); + border: 1px solid rgba(82, 194, 242, 0.4); + border-radius: 8px; + padding: 10px; + margin: 2px; + } + + #RightDeviceCard:hover { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, + stop:0 rgba(30, 45, 55, 0.9), + stop:1 rgba(42, 60, 75, 0.9)); + border: 1px solid rgba(82, 194, 242, 0.7); + } + + #DeviceName { + font-size: 12px; + color: #FFFFFF; + font-weight: 500; + } + + #DeviceStatus { + font-size: 10px; + color: #78909C; + } + + #FunctionBtn { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 rgba(46, 125, 180, 0.8), + stop:1 rgba(35, 95, 140, 0.8)); + color: #FFFFFF; + border: 1px solid rgba(82, 194, 242, 0.4); + border-radius: 6px; + padding: 10px 14px; + font-size: 12px; + font-weight: 500; + min-height: 36px; + } + + #FunctionBtn:hover { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 rgba(52, 140, 200, 0.9), + stop:1 rgba(40, 110, 160, 0.9)); + border: 1px solid rgba(82, 194, 242, 0.7); + } + + #FunctionBtn:pressed { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 rgba(30, 85, 125, 0.9), + stop:1 rgba(25, 65, 95, 0.9)); + } + + #FunctionBtn:disabled { + background-color: rgba(120, 144, 156, 0.5); + color: rgba(158, 158, 158, 0.7); + border: 1px solid rgba(120, 144, 156, 0.3); + } + + #StatLabel { + font-size: 12px; + color: #B0BEC5; + padding: 4px 0; + } + + #CallStatus { + font-size: 11px; + color: #78909C; + font-style: italic; + } + + #VolumeLabel { + font-size: 12px; + color: #B0BEC5; + } + + QSlider::groove:horizontal { + border: 1px solid rgba(82, 194, 242, 0.3); + height: 6px; + background: qlineargradient(x1:0, y1:0, x2:1, y2:0, + stop:0 rgba(25, 38, 48, 0.8), + stop:1 rgba(35, 50, 62, 0.8)); + border-radius: 3px; + } + + QSlider::handle:horizontal { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 rgba(82, 194, 242, 0.9), + stop:1 rgba(45, 120, 180, 0.9)); + border: 1px solid rgba(82, 194, 242, 0.6); + width: 16px; + margin: -5px 0; + border-radius: 8px; + } + + QSlider::handle:horizontal:hover { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 rgba(100, 210, 255, 1.0), + stop:1 rgba(60, 140, 200, 1.0)); + } + )"; + + setStyleSheet(styles); +} + +// 槽函数实现 +void RightFunctionPanel::onDeviceSelected(const QString &deviceName) +{ + m_selectedDevice = deviceName; + + // 更新设备选择状态 + m_robotDogCard->setActive(deviceName.contains("机器狗") || deviceName.contains("robot") || deviceName.contains("dog")); + m_droneCard->setActive(deviceName.contains("无人机") || deviceName.contains("drone") || deviceName.contains("uav")); + + // 根据设备类型启用/禁用相应按钮 + bool isRobotDog = deviceName.contains("机器狗") || deviceName.contains("robot") || deviceName.contains("dog"); + m_mappingBtn->setEnabled(isRobotDog); + m_navigationBtn->setEnabled(isRobotDog); + m_photoBtn->setEnabled(!isRobotDog); + m_recognitionBtn->setEnabled(!isRobotDog); +} + +void RightFunctionPanel::onMappingToggle() +{ + static bool isMappingActive = false; + isMappingActive = !isMappingActive; + + m_mappingBtn->setText(isMappingActive ? "停止建图" : "自主建图"); + m_mappingBtn->setStyleSheet(isMappingActive ? + "background-color: #DC143C;" : + ""); + + if (isMappingActive) { + emit startMapping(); + } else { + emit stopMapping(); + } +} + +void RightFunctionPanel::onNavigationToggle() +{ + static bool isNavigationActive = false; + isNavigationActive = !isNavigationActive; + + m_navigationBtn->setText(isNavigationActive ? "停止导航" : "导航避障"); + m_navigationBtn->setStyleSheet(isNavigationActive ? + "background-color: #DC143C;" : + ""); + + if (isNavigationActive) { + emit startNavigation(); + } else { + emit stopNavigation(); + } +} + +void RightFunctionPanel::onPhotoTransmissionToggle() +{ + static bool isTransmissionActive = false; + isTransmissionActive = !isTransmissionActive; + + m_photoBtn->setText(isTransmissionActive ? "停止传输" : "照片传输"); + m_photoBtn->setStyleSheet(isTransmissionActive ? + "background-color: #DC143C;" : + ""); + + if (isTransmissionActive) { + emit startPhotoTransmission(); + } else { + emit stopPhotoTransmission(); + } +} + +void RightFunctionPanel::onPersonRecognitionToggle() +{ + static bool isRecognitionActive = false; + isRecognitionActive = !isRecognitionActive; + + m_recognitionBtn->setText(isRecognitionActive ? "停止识别" : "人物识别"); + m_recognitionBtn->setStyleSheet(isRecognitionActive ? + "background-color: #DC143C;" : + ""); + + if (isRecognitionActive) { + emit startPersonRecognition(); + } else { + emit stopPersonRecognition(); + } +} + +void RightFunctionPanel::onVoiceCallToggle() +{ + m_isInCall = !m_isInCall; + + m_voiceCallBtn->setText(m_isInCall ? "结束通话" : "开始通话"); + m_voiceCallBtn->setStyleSheet(m_isInCall ? + "background-color: #DC143C;" : + ""); + m_muteBtn->setEnabled(m_isInCall); + m_callStatusLabel->setText(m_isInCall ? "通话中..." : "未连接"); + + if (m_isInCall) { + emit startVoiceCall(); + } else { + emit endVoiceCall(); + } +} + +void RightFunctionPanel::onRefreshStats() +{ + emit refreshEnemyStats(); + + // 模拟刷新效果 + m_refreshBtn->setText("刷新中..."); + m_refreshBtn->setEnabled(false); + + QTimer::singleShot(2000, [this]() { + m_refreshBtn->setText("刷新"); + m_refreshBtn->setEnabled(true); + }); +} + +void RightFunctionPanel::onAIAnalysis() +{ + emit requestAIAnalysis(); + + // 显示分析状态 + m_aiAnalysisBtn->setText("分析中..."); + m_aiAnalysisBtn->setEnabled(false); + + QTimer::singleShot(3000, [this]() { + m_aiAnalysisBtn->setText("AI分析"); + m_aiAnalysisBtn->setEnabled(true); + }); +} + +void RightFunctionPanel::updateEnemyStats(int totalEnemies, const QString &threatLevel) +{ + m_totalEnemiesLabel->setText(QString("已发现目标: %1").arg(totalEnemies)); + m_threatLevelLabel->setText(QString("威胁等级: %1").arg(threatLevel)); + + // 根据威胁等级设置颜色 + if (threatLevel == "高") { + m_threatLevelLabel->setStyleSheet("color: #DC143C; font-weight: bold;"); + } else if (threatLevel == "中") { + m_threatLevelLabel->setStyleSheet("color: #FF8C00; font-weight: bold;"); + } else { + m_threatLevelLabel->setStyleSheet("color: #4CAF50; font-weight: bold;"); + } +} + +void RightFunctionPanel::updateDeviceStatus(const QString &deviceName, bool online, int battery) +{ + RightDeviceCard *deviceCard = nullptr; + if (deviceName.contains("机器狗") || deviceName.contains("robot") || deviceName.contains("dog")) { + deviceCard = m_robotDogCard; + } else if (deviceName.contains("无人机") || deviceName.contains("drone") || deviceName.contains("uav")) { + deviceCard = m_droneCard; + } + + if (deviceCard) { + if (online) { + if (battery > 50) { + deviceCard->setStatus(QString("在线 %1%").arg(battery), QColor("#4CAF50")); + } else if (battery > 20) { + deviceCard->setStatus(QString("在线 %1%").arg(battery), QColor("#FF8C00")); + } else { + deviceCard->setStatus(QString("在线 %1%").arg(battery), QColor("#DC143C")); + } + } else { + deviceCard->setStatus("离线", QColor("#78909C")); + } + } +} + diff --git a/src/Client/src/ui/main/MainWindow.cpp b/src/Client/src/ui/main/MainWindow.cpp index b541d81..5b57da2 100644 --- a/src/Client/src/ui/main/MainWindow.cpp +++ b/src/Client/src/ui/main/MainWindow.cpp @@ -50,6 +50,7 @@ MainWindow::MainWindow(QWidget *parent) , m_ui(new Ui::MainWindow) , m_deviceListPanel(nullptr) , m_systemLogPanel(nullptr) + , m_rightFunctionPanel(nullptr) , m_leftPanelSplitter(nullptr) // , m_intelligenceUI(nullptr) // 暂时注释掉 { @@ -91,6 +92,9 @@ void MainWindow::setupUI() // 创建并集成SystemLogPanel和DeviceListPanel到左侧面板 setupSystemLogPanel(); + // 创建并集成右侧功能面板 + setupRightFunctionPanel(); + // 恢复地图显示控制 setupMapDisplay(); // 注意:原有的重复设备管理按钮已被移除,功能集成在DeviceListPanel中 @@ -176,6 +180,75 @@ void MainWindow::setupSystemLogPanel() } } +void MainWindow::setupRightFunctionPanel() +{ + // 创建右侧功能面板 + m_rightFunctionPanel = new RightFunctionPanel(this); + + // 获取右侧面板的布局 + QVBoxLayout *rightLayout = qobject_cast(m_ui->rightPanel->layout()); + if (rightLayout) { + // 彻底清除原有控件,避免UI冗余 + QLayoutItem *item; + while ((item = rightLayout->takeAt(0)) != nullptr) { + if (item->widget()) { + item->widget()->deleteLater(); + } + delete item; + } + + // 将右侧功能面板添加到右侧面板 + rightLayout->addWidget(m_rightFunctionPanel); + + // 连接右侧功能面板信号 + // 战场探索模块信号 + connect(m_rightFunctionPanel, &RightFunctionPanel::startMapping, + this, &MainWindow::onStartMapping); + connect(m_rightFunctionPanel, &RightFunctionPanel::stopMapping, + this, &MainWindow::onStopMapping); + connect(m_rightFunctionPanel, &RightFunctionPanel::startNavigation, + this, &MainWindow::onStartNavigation); + connect(m_rightFunctionPanel, &RightFunctionPanel::stopNavigation, + this, &MainWindow::onStopNavigation); + connect(m_rightFunctionPanel, &RightFunctionPanel::startPhotoTransmission, + this, &MainWindow::onStartPhotoTransmission); + connect(m_rightFunctionPanel, &RightFunctionPanel::stopPhotoTransmission, + this, &MainWindow::onStopPhotoTransmission); + connect(m_rightFunctionPanel, &RightFunctionPanel::startPersonRecognition, + this, &MainWindow::onStartPersonRecognition); + connect(m_rightFunctionPanel, &RightFunctionPanel::stopPersonRecognition, + this, &MainWindow::onStopPersonRecognition); + + // 情报传输模块信号 + connect(m_rightFunctionPanel, &RightFunctionPanel::startVoiceCall, + this, &MainWindow::onStartVoiceCall); + connect(m_rightFunctionPanel, &RightFunctionPanel::endVoiceCall, + this, &MainWindow::onEndVoiceCall); + + // 敌情统计模块信号 + connect(m_rightFunctionPanel, &RightFunctionPanel::refreshEnemyStats, + this, &MainWindow::onRefreshEnemyStats); + connect(m_rightFunctionPanel, &RightFunctionPanel::requestAIAnalysis, + this, &MainWindow::onRequestAIAnalysis); + connect(m_rightFunctionPanel, &RightFunctionPanel::exportReport, + this, &MainWindow::onExportReport); + + qDebug() << "RightFunctionPanel integrated successfully"; + SystemLogger::getInstance()->logInfo("右侧功能面板初始化完成"); + + // 模拟初始化一些设备状态 + QTimer::singleShot(1000, [this]() { + m_rightFunctionPanel->updateDeviceStatus("机器狗", true, 85); + m_rightFunctionPanel->updateDeviceStatus("无人机", true, 92); + m_rightFunctionPanel->updateEnemyStats(3, "中"); + }); + + } else { + qWarning() << "Failed to get right panel layout"; + SystemLogger::getInstance()->logError("右侧面板布局获取失败"); + } +} + void MainWindow::setupDeviceListPanel() { // 此方法已被setupSystemLogPanel()替代,保留以兼容可能的调用 @@ -1080,4 +1153,146 @@ bool MainWindow::addDeviceToDatabase(const QString &deviceId, const QString &nam db.close(); return success; +} + +// 右侧功能面板槽函数实现 +void MainWindow::onStartMapping() +{ + qDebug() << "Starting autonomous mapping..."; + SystemLogger::getInstance()->logInfo("开始自主建图"); + + // TODO: 实现自主建图功能 + // 这里应该连接到实际的机器狗建图系统 +} + +void MainWindow::onStopMapping() +{ + qDebug() << "Stopping autonomous mapping..."; + SystemLogger::getInstance()->logInfo("停止自主建图"); + + // TODO: 实现停止建图功能 +} + +void MainWindow::onStartNavigation() +{ + qDebug() << "Starting navigation and obstacle avoidance..."; + SystemLogger::getInstance()->logInfo("开始导航避障"); + + // TODO: 实现导航避障功能 +} + +void MainWindow::onStopNavigation() +{ + qDebug() << "Stopping navigation..."; + SystemLogger::getInstance()->logInfo("停止导航避障"); + + // TODO: 实现停止导航功能 +} + +void MainWindow::onStartPhotoTransmission() +{ + qDebug() << "Starting photo transmission from UAV..."; + SystemLogger::getInstance()->logInfo("开始无人机照片传输"); + + // TODO: 实现无人机照片传输功能 + // 这里应该连接到实际的无人机摄像头系统 +} + +void MainWindow::onStopPhotoTransmission() +{ + qDebug() << "Stopping photo transmission..."; + SystemLogger::getInstance()->logInfo("停止照片传输"); + + // TODO: 实现停止照片传输功能 +} + +void MainWindow::onStartPersonRecognition() +{ + qDebug() << "Starting person recognition..."; + SystemLogger::getInstance()->logInfo("开始人物识别"); + + // TODO: 实现人物识别功能 + // 这里应该连接到AI人物识别系统 +} + +void MainWindow::onStopPersonRecognition() +{ + qDebug() << "Stopping person recognition..."; + SystemLogger::getInstance()->logInfo("停止人物识别"); + + // TODO: 实现停止人物识别功能 +} + +void MainWindow::onStartVoiceCall() +{ + qDebug() << "Starting voice communication..."; + SystemLogger::getInstance()->logInfo("开始语音通话"); + + // TODO: 实现语音通话功能 + // 这里应该连接到实际的音频通信系统 +} + +void MainWindow::onEndVoiceCall() +{ + qDebug() << "Ending voice communication..."; + SystemLogger::getInstance()->logInfo("结束语音通话"); + + // TODO: 实现结束通话功能 +} + +void MainWindow::onRefreshEnemyStats() +{ + qDebug() << "Refreshing enemy statistics..."; + SystemLogger::getInstance()->logInfo("刷新敌情统计"); + + // TODO: 实现从数据库或AI系统获取最新敌情数据 + // 模拟数据更新 + if (m_rightFunctionPanel) { + // 模拟随机更新敌情数据 + int enemyCount = qrand() % 10 + 1; + QStringList threatLevels = {"低", "中", "高"}; + QString threatLevel = threatLevels[qrand() % threatLevels.size()]; + + m_rightFunctionPanel->updateEnemyStats(enemyCount, threatLevel); + + SystemLogger::getInstance()->logInfo( + QString("敌情统计更新:发现 %1 个目标,威胁等级:%2") + .arg(enemyCount).arg(threatLevel) + ); + } +} + +void MainWindow::onRequestAIAnalysis() +{ + qDebug() << "Requesting AI analysis..."; + SystemLogger::getInstance()->logInfo("请求AI敌情分析"); + + // TODO: 实现AI分析功能 + // 这里应该连接到大语言模型进行敌情分析 + + // 模拟AI分析结果 + QTimer::singleShot(3000, [this]() { + QString analysisResult = "AI分析结果:当前区域敌情相对稳定,建议继续监控北侧区域,注意东南方向可疑活动。"; + SystemLogger::getInstance()->logInfo("AI分析完成:" + analysisResult); + + // 可以通过消息框或状态栏显示分析结果 + QMessageBox::information(this, "AI敌情分析", analysisResult); + }); +} + +void MainWindow::onExportReport() +{ + qDebug() << "Exporting battlefield report..."; + SystemLogger::getInstance()->logInfo("导出战场报告"); + + // TODO: 实现报告导出功能 + // 这里应该生成包含敌情统计、设备状态、任务记录等的完整报告 + + // 模拟报告导出 + QString reportPath = QString("battlefield_report_%1.pdf") + .arg(QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss")); + + SystemLogger::getInstance()->logInfo("报告导出完成:" + reportPath); + QMessageBox::information(this, "报告导出", + QString("战场报告已成功导出到:\n%1").arg(reportPath)); } \ No newline at end of file