diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..0b2dbcc5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,49 @@
+# 编译生成文件 (Build artifacts)
+build/
+*.o
+*.so
+*.dll
+*.exe
+moc_*.cpp
+ui_*.h
+qrc_*.cpp
+Makefile
+
+# Qt临时文件 (Qt temporary files)
+*.pro.user
+*.pro.user.*
+.qmake.stash
+
+# 个人配置文件 (Personal configuration files)
+# 忽略个人数据库配置,避免团队成员间的配置冲突
+# Ignore personal database configuration to avoid conflicts between team members
+src/Client/config/database.ini
+
+# 环境配置文件 (Environment configuration files)
+.env
+.env.local
+.env.development
+.env.production
+
+# 日志文件 (Log files)
+*.log
+logs/
+
+# 临时文件 (Temporary files)
+*.tmp
+*.temp
+*~
+
+# IDE配置文件 (IDE configuration files)
+.vscode/
+.idea/
+*.swp
+*.swo
+
+# 系统文件 (System files)
+.DS_Store
+Thumbs.db
+
+# 备份文件 (Backup files)
+*.bak
+*.backup
\ No newline at end of file
diff --git a/.promptx/memory/declarative.md b/.promptx/memory/declarative.md
index 413302c6..c906ec1c 100644
--- a/.promptx/memory/declarative.md
+++ b/.promptx/memory/declarative.md
@@ -248,4 +248,14 @@
用户明确表示大模型只是侧重点,后面会专门用一章详细介绍大模型编码经验和技巧。 --tags 第二章节完成 软件工程实践 内容比重调整 大模型辅助定位
--tags #流程管理 #工具使用 #评分:8 #有效期:长期
+- END
+
+- 2025/07/03 10:44 START
+成功创建了专业的Qt界面优化专家角色(qt-ui-optimizer),专门针对学术项目的界面质量提升。角色具备完整的Qt 5.15技术栈、UI/UX设计原则、学术评分标准知识,采用专业专家模式设计,包含UI设计思维、学术标准意识、Qt优化工作流程等核心能力模块,能够提供从界面分析到代码实现的完整优化方案。 --tags 角色创建 Qt界面优化 学术项目 UI设计 专业专家模式
+--tags #流程管理 #评分:8 #有效期:长期
+- END
+
+- 2025/07/03 15:12 START
+BattlefieldExplorationSystem项目样式管理系统优化完成:1)完全消除48个CSS3兼容性错误,修复transition、transform、box-shadow等不支持属性;2)建立双管理器架构(ModernStyleManager统一管理+LeftPanelStyleManager专用管理);3)统一样式文件到src/Client/styles/目录,清理旧的res/styles/目录;4)移除MainWindow内联样式,完全使用现代样式管理器;5)支持4种主题和演示模式,专为学术展示优化;6)创建完整文档体系(README.md、USAGE_GUIDE.md、StyleSystemStatus.md);7)实现Qt 5.15完全兼容,零错误稳定运行 --tags Qt样式管理 CSS3兼容性 ModernStyleManager 学术项目优化 界面美化
+--tags #其他 #评分:8 #有效期:长期
- END
\ No newline at end of file
diff --git a/.promptx/pouch.json b/.promptx/pouch.json
index 517fb10b..7a74643d 100644
--- a/.promptx/pouch.json
+++ b/.promptx/pouch.json
@@ -1,5 +1,5 @@
{
- "currentState": "memory_saved",
+ "currentState": "role_activated_with_memory",
"stateHistory": [
{
"from": "initial",
@@ -346,7 +346,89 @@
"--tags",
"PR同步 系统问题 架构设计 性能优化"
]
+ },
+ {
+ "from": "memory_saved",
+ "command": "init",
+ "timestamp": "2025-07-03T04:08:57.610Z",
+ "args": [
+ {
+ "workingDirectory": "/home/hzk/Software_Architecture"
+ }
+ ]
+ },
+ {
+ "from": "initialized",
+ "command": "welcome",
+ "timestamp": "2025-07-03T04:09:02.202Z",
+ "args": []
+ },
+ {
+ "from": "role_discovery",
+ "command": "action",
+ "timestamp": "2025-07-03T04:09:15.431Z",
+ "args": [
+ "qt-ui-optimizer"
+ ]
+ },
+ {
+ "from": "role_activated_with_memory",
+ "command": "init",
+ "timestamp": "2025-07-03T06:24:58.574Z",
+ "args": [
+ {
+ "workingDirectory": "/home/hzk/Software_Architecture"
+ }
+ ]
+ },
+ {
+ "from": "initialized",
+ "command": "welcome",
+ "timestamp": "2025-07-03T06:25:02.931Z",
+ "args": []
+ },
+ {
+ "from": "role_discovery",
+ "command": "action",
+ "timestamp": "2025-07-03T06:25:43.488Z",
+ "args": [
+ "qt-ui-optimizer"
+ ]
+ },
+ {
+ "from": "role_activated_with_memory",
+ "command": "remember",
+ "timestamp": "2025-07-03T07:12:05.100Z",
+ "args": [
+ "BattlefieldExplorationSystem项目样式管理系统优化完成:1)完全消除48个CSS3兼容性错误,修复transition、transform、box-shadow等不支持属性;2)建立双管理器架构(ModernStyleManager统一管理+LeftPanelStyleManager专用管理);3)统一样式文件到src/Client/styles/目录,清理旧的res/styles/目录;4)移除MainWindow内联样式,完全使用现代样式管理器;5)支持4种主题和演示模式,专为学术展示优化;6)创建完整文档体系(README.md、USAGE_GUIDE.md、StyleSystemStatus.md);7)实现Qt 5.15完全兼容,零错误稳定运行",
+ "--tags",
+ "Qt样式管理 CSS3兼容性 ModernStyleManager 学术项目优化 界面美化"
+ ]
+ },
+ {
+ "from": "memory_saved",
+ "command": "init",
+ "timestamp": "2025-07-03T12:28:21.050Z",
+ "args": [
+ {
+ "workingDirectory": "/home/hzk/Software_Architecture"
+ }
+ ]
+ },
+ {
+ "from": "initialized",
+ "command": "welcome",
+ "timestamp": "2025-07-03T12:28:46.995Z",
+ "args": []
+ },
+ {
+ "from": "role_discovery",
+ "command": "action",
+ "timestamp": "2025-07-03T12:29:07.708Z",
+ "args": [
+ "qt-ui-optimizer"
+ ]
}
],
- "lastUpdated": "2025-07-01T07:51:59.368Z"
+ "lastUpdated": "2025-07-03T12:29:07.735Z"
}
diff --git a/.promptx/resource/domain/qt-ui-optimizer/execution/academic-ui-standards.execution.md b/.promptx/resource/domain/qt-ui-optimizer/execution/academic-ui-standards.execution.md
new file mode 100644
index 00000000..95ffd464
--- /dev/null
+++ b/.promptx/resource/domain/qt-ui-optimizer/execution/academic-ui-standards.execution.md
@@ -0,0 +1,126 @@
+
+
+ ## 学术项目界面约束
+ - **评分时间限制**:界面需要在短时间内给老师留下深刻印象
+ - **演示环境约束**:需要适应课堂投影和不同显示设备
+ - **功能展示要求**:界面必须能清晰展现所有核心功能
+ - **团队协作体现**:界面需要体现团队分工和技术整合
+ - **文档配合约束**:界面设计需要与技术文档保持一致
+
+
+
+ ## 学术界面强制标准
+ - **功能完整性优先**:所有要求功能必须有对应界面入口
+ - **专业性体现必须**:界面必须体现学生的技术水平
+ - **演示友好性**:界面必须便于课堂演示和功能展示
+ - **创新点突出**:必须有超出基本要求的设计亮点
+ - **稳定性保证**:演示过程中不能出现界面错误
+
+
+
+ ## 学术界面设计指南
+ - **第一印象优化**:应用启动后的首屏要专业美观
+ - **核心功能突出**:主要功能入口要显眼易找
+ - **技术深度展现**:通过界面细节体现技术实力
+ - **用户引导清晰**:操作流程要直观易懂
+ - **错误处理完善**:异常情况要有友好提示
+
+
+
+ ## 学术界面标准化流程
+
+ ### 评分标准对齐检查
+ ```mermaid
+ graph TD
+ A[功能完整性检查] --> B[专业美观度评估]
+ B --> C[用户体验测试]
+ C --> D[技术深度体现]
+ D --> E[创新亮点识别]
+ E --> F[演示效果验证]
+ F --> G{达到学术标准?}
+ G -->|是| H[标准合格]
+ G -->|否| I[针对性改进]
+ I --> A
+ ```
+
+ ### 老师评分视角模拟
+ ```mermaid
+ flowchart LR
+ A[应用启动] --> B[第一印象评分]
+ B --> C[功能演示]
+ C --> D[交互体验]
+ D --> E[技术亮点]
+ E --> F[整体评价]
+ F --> G[最终评分]
+ ```
+
+ **评分关键节点:**
+ 1. **启动印象** (20%):应用启动速度和首屏效果
+ 2. **功能展示** (30%):核心功能的界面表现
+ 3. **交互体验** (25%):操作流程的流畅度
+ 4. **技术深度** (15%):界面体现的技术水平
+ 5. **创新亮点** (10%):超出预期的设计创新
+
+ ### 差异化竞争策略
+ ```mermaid
+ mindmap
+ root((竞争优势))
+ 技术深度
+ 复杂QSS样式
+ 自定义控件
+ 高级布局技巧
+ 视觉设计
+ 现代化UI风格
+ 专业配色方案
+ 精致图标设计
+ 交互创新
+ 流畅动画效果
+ 智能操作引导
+ 个性化设置
+ 功能完整
+ 全面功能覆盖
+ 异常处理完善
+ 性能优化到位
+ ```
+
+
+
+ ## 学术界面评分标准
+
+ ### 功能完整性 (30分)
+ - ✅ 所有要求功能都有界面入口 (10分)
+ - ✅ 功能操作流程完整清晰 (10分)
+ - ✅ 异常情况处理完善 (5分)
+ - ✅ 界面与功能逻辑一致 (5分)
+
+ ### 专业美观度 (25分)
+ - ✅ 整体视觉设计专业 (8分)
+ - ✅ 色彩搭配协调统一 (6分)
+ - ✅ 控件样式现代美观 (6分)
+ - ✅ 布局合理有序 (5分)
+
+ ### 用户体验 (20分)
+ - ✅ 操作流程直观简洁 (8分)
+ - ✅ 界面响应及时准确 (6分)
+ - ✅ 错误提示友好明确 (3分)
+ - ✅ 学习成本低 (3分)
+
+ ### 技术深度 (15分)
+ - ✅ Qt技术运用熟练 (6分)
+ - ✅ 代码结构清晰规范 (4分)
+ - ✅ 性能优化到位 (3分)
+ - ✅ 跨平台兼容性好 (2分)
+
+ ### 创新亮点 (10分)
+ - ✅ 有超出基本要求的设计 (4分)
+ - ✅ 技术实现有创新性 (3分)
+ - ✅ 用户体验有独特之处 (2分)
+ - ✅ 整体方案有思考深度 (1分)
+
+ ### 演示效果加分项
+ - 🌟 界面启动给人惊艳感 (+2分)
+ - 🌟 功能演示流畅无卡顿 (+2分)
+ - 🌟 细节处理体现工匠精神 (+1分)
+ - 🌟 整体方案体现团队协作 (+1分)
+
+
diff --git a/.promptx/resource/domain/qt-ui-optimizer/execution/qt-optimization-workflow.execution.md b/.promptx/resource/domain/qt-ui-optimizer/execution/qt-optimization-workflow.execution.md
new file mode 100644
index 00000000..a57e0733
--- /dev/null
+++ b/.promptx/resource/domain/qt-ui-optimizer/execution/qt-optimization-workflow.execution.md
@@ -0,0 +1,156 @@
+
+
+ ## Qt界面优化技术约束
+ - **Qt版本限制**:必须兼容Qt 5.15,不能使用更高版本特性
+ - **C++标准**:遵循C++17标准,确保代码兼容性
+ - **性能要求**:界面优化不能显著影响应用性能
+ - **跨平台兼容**:确保Windows、Linux、macOS平台一致性
+ - **维护性约束**:代码必须清晰可读,便于后续维护
+
+
+
+ ## Qt优化强制规则
+ - **功能优先原则**:界面优化不能破坏现有功能
+ - **渐进式改进**:采用小步快跑的优化策略,避免大规模重构
+ - **代码规范遵循**:严格遵循Qt编程规范和C++最佳实践
+ - **测试验证必须**:每次优化后必须进行功能测试
+ - **备份保护**:优化前必须备份原始代码
+
+
+
+ ## Qt优化指导原则
+ - **用户体验导向**:所有优化都应以提升用户体验为目标
+ - **学术标准对齐**:优化方案要符合学术项目评分要求
+ - **技术深度体现**:通过界面优化展现Qt技术掌握程度
+ - **现代化设计**:采用当前主流的UI设计理念
+ - **可扩展性考虑**:为未来功能扩展预留界面空间
+
+
+
+ ## Qt界面优化标准流程
+
+ ### Phase 1: 现状分析 (30分钟)
+ ```mermaid
+ flowchart TD
+ A[启动应用] --> B[界面截图记录]
+ B --> C[功能模块梳理]
+ C --> D[问题点识别]
+ D --> E[优先级排序]
+ E --> F[优化目标确定]
+ ```
+
+ **具体执行步骤:**
+ 1. **界面审查**:逐个界面截图,记录当前状态
+ 2. **功能测试**:验证所有功能的界面表现
+ 3. **问题清单**:列出美观度、用户体验、技术实现问题
+ 4. **影响评估**:评估每个问题对学术评分的影响程度
+ 5. **资源评估**:评估修复每个问题所需的时间和技术难度
+
+ ### Phase 2: 优化方案设计 (45分钟)
+ ```mermaid
+ graph TD
+ A[问题分析] --> B{优化类型}
+ B -->|布局优化| C[Layout Manager调整]
+ B -->|样式美化| D[QSS样式表设计]
+ B -->|交互改进| E[信号槽机制优化]
+ B -->|控件升级| F[自定义控件开发]
+ C --> G[方案整合]
+ D --> G
+ E --> G
+ F --> G
+ G --> H[技术可行性验证]
+ ```
+
+ **设计输出物:**
+ - **布局方案**:新的界面布局设计图
+ - **样式表**:完整的QSS样式代码
+ - **交互流程**:优化后的用户操作流程
+ - **技术方案**:具体的Qt实现方法
+
+ ### Phase 3: 代码实现 (90分钟)
+ ```mermaid
+ flowchart LR
+ A[环境准备] --> B[样式表实现]
+ B --> C[布局调整]
+ C --> D[控件美化]
+ D --> E[交互优化]
+ E --> F[性能测试]
+ F --> G[跨平台验证]
+ ```
+
+ **实现优先级:**
+ 1. **QSS样式表**:优先实现视觉效果提升
+ 2. **布局管理器**:调整控件排列和间距
+ 3. **控件属性**:设置控件的外观属性
+ 4. **信号槽连接**:优化交互响应逻辑
+ 5. **自定义绘制**:实现特殊视觉效果
+
+ ### Phase 4: 质量验证 (30分钟)
+ ```mermaid
+ graph TD
+ A[功能测试] --> B[界面测试]
+ B --> C[性能测试]
+ C --> D[兼容性测试]
+ D --> E{质量达标?}
+ E -->|是| F[优化完成]
+ E -->|否| G[问题修复]
+ G --> A
+ ```
+
+ **验证检查清单:**
+ - ✅ 所有原有功能正常工作
+ - ✅ 界面在不同分辨率下正常显示
+ - ✅ 应用启动和响应速度无明显下降
+ - ✅ 样式在不同操作系统下一致
+ - ✅ 界面符合学术项目专业标准
+
+ ### Phase 5: 文档输出 (15分钟)
+ ```mermaid
+ flowchart LR
+ A[优化总结] --> B[代码说明]
+ B --> C[设计理念]
+ C --> D[技术亮点]
+ D --> E[使用指南]
+ ```
+
+ **文档内容:**
+ - **优化报告**:问题分析、解决方案、效果对比
+ - **代码注释**:关键代码的实现原理说明
+ - **设计说明**:界面设计的理论依据
+ - **维护指南**:后续修改和扩展的建议
+
+
+
+ ## Qt优化质量标准
+
+ ### 功能完整性
+ - ✅ 原有功能100%保持正常
+ - ✅ 新增交互逻辑符合预期
+ - ✅ 异常情况处理完善
+ - ✅ 界面响应及时准确
+
+ ### 视觉专业度
+ - ✅ 色彩搭配协调统一
+ - ✅ 字体排版清晰美观
+ - ✅ 控件样式现代化
+ - ✅ 布局合理有序
+
+ ### 用户体验
+ - ✅ 操作流程直观简洁
+ - ✅ 反馈信息及时明确
+ - ✅ 学习成本低
+ - ✅ 错误处理友好
+
+ ### 技术实现
+ - ✅ 代码结构清晰
+ - ✅ 性能影响最小
+ - ✅ 跨平台兼容
+ - ✅ 维护性良好
+
+ ### 学术标准
+ - ✅ 体现Qt技术深度
+ - ✅ 符合课程要求
+ - ✅ 具备演示价值
+ - ✅ 有创新亮点
+
+
diff --git a/.promptx/resource/domain/qt-ui-optimizer/knowledge/academic-project-standards.knowledge.md b/.promptx/resource/domain/qt-ui-optimizer/knowledge/academic-project-standards.knowledge.md
new file mode 100644
index 00000000..0514dbbf
--- /dev/null
+++ b/.promptx/resource/domain/qt-ui-optimizer/knowledge/academic-project-standards.knowledge.md
@@ -0,0 +1,239 @@
+# 学术项目界面标准与评分体系
+
+## 高校软件工程课程评分标准
+
+### 界面评分权重分析
+```
+软件工程课程项目评分构成:
+├── 需求分析与设计 (25%)
+├── 代码实现质量 (30%)
+├── 界面设计与用户体验 (20%) ← 重点关注
+├── 测试与文档 (15%)
+└── 创新与展示 (10%)
+
+界面评分细分:
+├── 功能完整性 (40%) - 8分
+├── 视觉设计质量 (30%) - 6分
+├── 用户体验 (20%) - 4分
+└── 技术实现深度 (10%) - 2分
+```
+
+### 老师评分关注点
+1. **第一印象效应** (30秒内)
+ - 应用启动速度和稳定性
+ - 主界面的专业美观度
+ - 功能布局的合理性
+
+2. **功能演示效果** (5-10分钟)
+ - 核心功能的界面表现
+ - 操作流程的流畅性
+ - 异常处理的完善性
+
+3. **技术深度体现** (细节观察)
+ - Qt技术的熟练运用
+ - 代码结构的清晰性
+ - 界面响应的及时性
+
+## 学术项目界面特殊要求
+
+### 演示环境适配
+```
+课堂演示环境特点:
+- 投影仪分辨率:1024x768 或 1920x1080
+- 显示延迟:可能存在1-2秒延迟
+- 观看距离:3-5米
+- 光线条件:可能较亮,对比度要求高
+
+适配策略:
+- 字体大小:最小14px,推荐16px+
+- 色彩对比:高对比度配色方案
+- 界面元素:适当放大,便于远距离观看
+- 操作反馈:明显的视觉反馈效果
+```
+
+### 功能展示优化
+```
+核心功能界面设计原则:
+1. 入口显眼:主要功能按钮要大且明显
+2. 流程清晰:操作步骤要有明确的视觉引导
+3. 结果突出:功能执行结果要有明显展示
+4. 错误友好:异常情况要有清晰的提示信息
+```
+
+### 团队协作体现
+```
+多人协作项目界面设计:
+- 模块划分清晰:不同模块有明显的界面区分
+- 风格统一:整体界面风格保持一致
+- 集成无缝:各模块间的界面切换自然
+- 功能完整:每个团队成员的工作都有界面体现
+```
+
+## 与商业项目的差异
+
+### 评分导向 vs 用户导向
+```
+学术项目特点:
+- 目标用户:老师和同学
+- 使用时间:短期演示
+- 评价标准:技术深度和完整性
+- 创新要求:鼓励技术创新和尝试
+
+商业项目特点:
+- 目标用户:真实用户群体
+- 使用时间:长期使用
+- 评价标准:用户满意度和商业价值
+- 稳定要求:强调稳定性和可维护性
+```
+
+### 技术展示 vs 实用性
+```
+学术项目界面设计重点:
+1. 技术深度展示:通过界面体现Qt技术掌握程度
+2. 完整性体现:所有功能都要有对应界面
+3. 创新亮点:有超出基本要求的设计创新
+4. 演示效果:便于课堂演示和功能展示
+
+实际应用考虑:
+- 可以适当牺牲一些实用性来突出技术亮点
+- 界面可以相对复杂,展示更多技术特性
+- 允许一定的学习成本,重点是功能完整性
+```
+
+## 常见评分陷阱
+
+### 功能不完整
+```
+典型问题:
+- 界面有按钮但功能未实现
+- 部分模块缺少界面入口
+- 异常情况没有界面提示
+- 数据展示不完整
+
+避免策略:
+- 制作功能清单,逐一检查界面实现
+- 测试所有界面元素的功能完整性
+- 为每个功能提供完整的操作流程
+- 确保异常情况有友好的界面提示
+```
+
+### 界面不专业
+```
+典型问题:
+- 使用Qt默认样式,没有美化
+- 布局混乱,元素排列不整齐
+- 色彩搭配不协调
+- 字体大小不统一
+
+提升策略:
+- 使用QSS样式表进行界面美化
+- 采用网格布局,确保元素对齐
+- 选择专业的配色方案
+- 建立统一的字体规范
+```
+
+### 用户体验差
+```
+典型问题:
+- 操作流程不直观
+- 缺少操作反馈
+- 错误提示不友好
+- 界面响应慢
+
+改进方法:
+- 简化操作流程,减少点击次数
+- 为所有操作提供及时反馈
+- 使用友好的错误提示语言
+- 优化界面响应性能
+```
+
+## 创新加分策略
+
+### 技术创新点
+```
+Qt高级特性应用:
+- 自定义控件开发
+- 复杂动画效果实现
+- 多线程界面更新
+- 插件化界面架构
+- 主题切换功能
+```
+
+### 设计创新点
+```
+界面设计创新:
+- 独特的交互方式
+- 创新的信息展示方法
+- 个性化的用户界面
+- 智能化的操作引导
+- 沉浸式的用户体验
+```
+
+### 功能创新点
+```
+功能实现创新:
+- 智能化的数据分析界面
+- 实时的状态监控面板
+- 可视化的配置管理
+- 自适应的界面布局
+- 多模态的交互支持
+```
+
+## 评分提升技巧
+
+### 细节优化
+```
+界面细节提升:
+- 图标设计:使用统一风格的图标
+- 加载动画:为耗时操作添加加载指示
+- 状态指示:清晰的状态显示
+- 快捷键:为常用功能提供快捷键
+- 工具提示:为复杂功能提供说明
+```
+
+### 演示准备
+```
+演示前检查清单:
+□ 所有功能都能正常演示
+□ 界面在投影仪上显示清晰
+□ 操作流程已经熟练掌握
+□ 异常情况有应对方案
+□ 技术亮点准备好说明
+□ 团队分工清晰明确
+```
+
+### 文档配合
+```
+界面设计文档:
+- 界面设计说明:设计理念和原则
+- 技术实现文档:关键技术的实现方法
+- 用户操作手册:详细的操作指南
+- 测试报告:界面功能的测试结果
+- 创新点说明:技术创新和设计创新的详细说明
+```
+
+## 评分标准对照表
+
+### 优秀项目特征 (90-100分)
+- ✅ 界面专业美观,有明显的设计感
+- ✅ 功能完整,所有模块都有完善的界面
+- ✅ 用户体验优秀,操作直观流畅
+- ✅ 技术实现深度,体现Qt高级特性
+- ✅ 有创新亮点,超出基本要求
+- ✅ 演示效果出色,给人深刻印象
+
+### 良好项目特征 (80-89分)
+- ✅ 界面整洁美观,有一定的设计水平
+- ✅ 功能基本完整,主要模块界面完善
+- ✅ 用户体验良好,操作相对流畅
+- ✅ 技术实现规范,Qt技术运用熟练
+- ✅ 有一定创新,部分功能有亮点
+- ✅ 演示效果良好,功能展示清晰
+
+### 及格项目特征 (60-79分)
+- ✅ 界面基本整洁,满足基本美观要求
+- ✅ 主要功能有界面,基本功能完整
+- ✅ 用户体验一般,操作基本可用
+- ✅ 技术实现基础,Qt基本特性运用正确
+- ✅ 创新有限,主要是基础功能实现
+- ✅ 演示基本成功,功能能够展示
diff --git a/.promptx/resource/domain/qt-ui-optimizer/knowledge/qt-ui-development.knowledge.md b/.promptx/resource/domain/qt-ui-optimizer/knowledge/qt-ui-development.knowledge.md
new file mode 100644
index 00000000..2054aa99
--- /dev/null
+++ b/.promptx/resource/domain/qt-ui-optimizer/knowledge/qt-ui-development.knowledge.md
@@ -0,0 +1,266 @@
+# Qt 5.15 界面开发核心知识
+
+## QSS样式表精通
+
+### 基础语法结构
+```css
+/* 选择器语法 */
+QWidget { background-color: #f0f0f0; }
+QPushButton#myButton { color: blue; }
+QLabel[class="title"] { font-size: 18px; }
+
+/* 伪状态选择器 */
+QPushButton:hover { background-color: #e0e0e0; }
+QPushButton:pressed { background-color: #d0d0d0; }
+QPushButton:disabled { color: gray; }
+```
+
+### 现代化按钮样式
+```css
+QPushButton {
+ background-color: #4CAF50;
+ border: none;
+ color: white;
+ padding: 8px 16px;
+ border-radius: 4px;
+ font-size: 14px;
+ font-weight: bold;
+}
+
+QPushButton:hover {
+ background-color: #45a049;
+}
+
+QPushButton:pressed {
+ background-color: #3d8b40;
+}
+```
+
+### 输入框美化
+```css
+QLineEdit {
+ border: 2px solid #ddd;
+ border-radius: 6px;
+ padding: 8px;
+ font-size: 14px;
+ background-color: white;
+}
+
+QLineEdit:focus {
+ border-color: #4CAF50;
+ outline: none;
+}
+```
+
+## 布局管理器精通
+
+### QVBoxLayout 垂直布局
+```cpp
+QVBoxLayout *layout = new QVBoxLayout;
+layout->addWidget(titleLabel);
+layout->addSpacing(10); // 添加间距
+layout->addWidget(contentWidget);
+layout->addStretch(); // 添加弹性空间
+layout->setContentsMargins(20, 20, 20, 20); // 设置边距
+```
+
+### QGridLayout 网格布局
+```cpp
+QGridLayout *gridLayout = new QGridLayout;
+gridLayout->addWidget(label1, 0, 0);
+gridLayout->addWidget(lineEdit1, 0, 1);
+gridLayout->addWidget(label2, 1, 0);
+gridLayout->addWidget(lineEdit2, 1, 1);
+gridLayout->setColumnStretch(1, 1); // 第二列可拉伸
+```
+
+### QHBoxLayout 水平布局
+```cpp
+QHBoxLayout *buttonLayout = new QHBoxLayout;
+buttonLayout->addStretch();
+buttonLayout->addWidget(okButton);
+buttonLayout->addWidget(cancelButton);
+```
+
+## 控件美化技巧
+
+### QTableWidget 表格美化
+```css
+QTableWidget {
+ gridline-color: #e0e0e0;
+ background-color: white;
+ alternate-background-color: #f9f9f9;
+}
+
+QTableWidget::item {
+ padding: 8px;
+ border: none;
+}
+
+QTableWidget::item:selected {
+ background-color: #4CAF50;
+ color: white;
+}
+
+QHeaderView::section {
+ background-color: #f5f5f5;
+ padding: 8px;
+ border: 1px solid #ddd;
+ font-weight: bold;
+}
+```
+
+### QComboBox 下拉框美化
+```css
+QComboBox {
+ border: 2px solid #ddd;
+ border-radius: 6px;
+ padding: 6px;
+ min-width: 120px;
+}
+
+QComboBox::drop-down {
+ border: none;
+ width: 20px;
+}
+
+QComboBox::down-arrow {
+ image: url(:/icons/down-arrow.png);
+ width: 12px;
+ height: 12px;
+}
+```
+
+## 自定义控件开发
+
+### 自定义按钮类
+```cpp
+class CustomButton : public QPushButton {
+ Q_OBJECT
+public:
+ CustomButton(const QString &text, QWidget *parent = nullptr);
+
+protected:
+ void paintEvent(QPaintEvent *event) override;
+ void enterEvent(QEvent *event) override;
+ void leaveEvent(QEvent *event) override;
+
+private:
+ bool m_hovered;
+ QPropertyAnimation *m_animation;
+};
+```
+
+### 渐变背景实现
+```cpp
+void CustomWidget::paintEvent(QPaintEvent *event) {
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing);
+
+ QLinearGradient gradient(0, 0, 0, height());
+ gradient.setColorAt(0, QColor(240, 240, 240));
+ gradient.setColorAt(1, QColor(220, 220, 220));
+
+ painter.fillRect(rect(), gradient);
+}
+```
+
+## 信号槽机制优化
+
+### Lambda表达式连接
+```cpp
+connect(button, &QPushButton::clicked, [this]() {
+ // 处理点击事件
+ updateUI();
+});
+```
+
+### 自定义信号定义
+```cpp
+class CustomWidget : public QWidget {
+ Q_OBJECT
+signals:
+ void dataChanged(const QString &data);
+ void statusUpdated(int status);
+
+public slots:
+ void onDataReceived(const QByteArray &data);
+ void onStatusChanged(bool connected);
+};
+```
+
+## 性能优化技巧
+
+### 减少重绘次数
+```cpp
+// 批量更新时禁用重绘
+widget->setUpdatesEnabled(false);
+// 执行多个更新操作
+widget->setUpdatesEnabled(true);
+widget->update(); // 手动触发重绘
+```
+
+### 使用样式表缓存
+```cpp
+// 在类初始化时设置样式表,避免重复设置
+static const QString buttonStyle =
+ "QPushButton { background-color: #4CAF50; }";
+button->setStyleSheet(buttonStyle);
+```
+
+## 响应式设计
+
+### 自适应布局
+```cpp
+void MainWindow::resizeEvent(QResizeEvent *event) {
+ QMainWindow::resizeEvent(event);
+
+ // 根据窗口大小调整布局
+ if (width() < 800) {
+ // 小屏幕布局
+ switchToCompactLayout();
+ } else {
+ // 大屏幕布局
+ switchToNormalLayout();
+ }
+}
+```
+
+### DPI适配
+```cpp
+// 获取系统DPI缩放比例
+qreal dpiScale = qApp->devicePixelRatio();
+int scaledSize = static_cast(16 * dpiScale);
+font.setPixelSize(scaledSize);
+```
+
+## 国际化支持
+
+### 文本国际化
+```cpp
+// 在代码中使用tr()函数
+button->setText(tr("确定"));
+label->setText(tr("用户名:"));
+
+// 在.pro文件中添加
+TRANSLATIONS += app_zh_CN.ts app_en_US.ts
+```
+
+## 调试和测试
+
+### 样式表调试
+```cpp
+// 运行时修改样式表进行调试
+#ifdef QT_DEBUG
+ widget->setStyleSheet("border: 1px solid red;"); // 调试边框
+#endif
+```
+
+### 性能监控
+```cpp
+// 使用QElapsedTimer监控性能
+QElapsedTimer timer;
+timer.start();
+// 执行耗时操作
+qDebug() << "操作耗时:" << timer.elapsed() << "ms";
+```
diff --git a/.promptx/resource/domain/qt-ui-optimizer/knowledge/ui-ux-principles.knowledge.md b/.promptx/resource/domain/qt-ui-optimizer/knowledge/ui-ux-principles.knowledge.md
new file mode 100644
index 00000000..1bc8d651
--- /dev/null
+++ b/.promptx/resource/domain/qt-ui-optimizer/knowledge/ui-ux-principles.knowledge.md
@@ -0,0 +1,208 @@
+# UI/UX设计原则与最佳实践
+
+## 现代UI设计原则
+
+### Material Design 核心理念
+- **物理隐喻**:界面元素模拟真实世界的物理特性
+- **大胆的图形设计**:使用鲜明的色彩和清晰的层次
+- **有意义的动画**:动画应该有目的性,引导用户注意力
+- **自适应设计**:界面应该适应不同的屏幕尺寸和设备
+
+### Fluent Design 设计语言
+- **光线**:使用光线效果突出重要元素
+- **深度**:通过阴影和层次创建空间感
+- **动画**:流畅自然的过渡动画
+- **材质**:半透明和模糊效果的运用
+
+## 色彩设计理论
+
+### 色彩心理学应用
+```
+主色调选择指南:
+- 蓝色:专业、可信、科技感 (适合企业应用)
+- 绿色:自然、安全、成功 (适合健康、金融应用)
+- 红色:紧急、重要、激情 (适合警告、重要操作)
+- 灰色:中性、专业、现代 (适合工具类应用)
+```
+
+### 配色方案设计
+```
+经典配色组合:
+1. 单色配色:同一色相的不同明度和饱和度
+2. 互补配色:色轮上相对的两种颜色
+3. 三角配色:色轮上等距的三种颜色
+4. 分裂互补:一种主色加上其互补色的邻近色
+```
+
+### 无障碍设计考虑
+- **对比度要求**:文字与背景对比度至少4.5:1
+- **色盲友好**:不能仅依靠颜色传达信息
+- **色彩测试**:使用色盲模拟器测试界面效果
+
+## 排版设计原则
+
+### 字体层次设计
+```
+字体大小层次:
+- 主标题:24-32px,粗体
+- 副标题:18-24px,中等粗细
+- 正文:14-16px,常规
+- 说明文字:12-14px,细体
+- 标签文字:10-12px,大写
+```
+
+### 行距和间距
+```
+间距设计规则:
+- 行距:字体大小的1.2-1.5倍
+- 段落间距:行距的1.5-2倍
+- 元素间距:8px的倍数 (8, 16, 24, 32...)
+- 页面边距:至少16px,推荐24-32px
+```
+
+### 字体选择原则
+- **可读性优先**:选择清晰易读的字体
+- **系统字体**:优先使用系统默认字体
+- **字体数量**:一个界面最多使用2-3种字体
+- **中英文搭配**:确保中英文字体协调统一
+
+## 布局设计原则
+
+### 网格系统应用
+```
+12列网格系统:
+- 容器宽度:1200px (桌面)
+- 列宽:75px
+- 间距:30px
+- 边距:15px
+```
+
+### 视觉层次构建
+```
+层次设计方法:
+1. 大小对比:重要元素使用更大尺寸
+2. 颜色对比:重要元素使用突出颜色
+3. 位置对比:重要元素放在显眼位置
+4. 空白空间:用留白突出重要内容
+```
+
+### F型和Z型布局
+- **F型布局**:适合内容密集的界面,用户从左到右、从上到下浏览
+- **Z型布局**:适合简洁界面,引导用户视线按Z字形移动
+
+## 交互设计原则
+
+### 可用性启发式原则
+1. **系统状态可见性**:用户应该知道系统当前状态
+2. **系统与现实匹配**:使用用户熟悉的概念和语言
+3. **用户控制和自由**:提供撤销和重做功能
+4. **一致性和标准**:遵循平台约定和标准
+5. **错误预防**:设计时预防用户犯错
+6. **识别而非回忆**:让选项可见,减少记忆负担
+7. **使用灵活性和效率**:为专家用户提供快捷方式
+8. **美观和简约设计**:避免无关信息干扰
+9. **帮助用户识别、诊断和从错误中恢复**:错误信息要清晰
+10. **帮助和文档**:提供必要的帮助信息
+
+### 反馈机制设计
+```
+反馈类型和时机:
+- 即时反馈:按钮点击、输入验证 (<100ms)
+- 短期反馈:表单提交、数据保存 (1-3秒)
+- 长期反馈:文件上传、数据处理 (>3秒,需要进度指示)
+```
+
+### 状态设计
+```
+控件状态设计:
+- 默认状态:控件的初始外观
+- 悬停状态:鼠标悬停时的视觉反馈
+- 激活状态:控件被点击或选中时
+- 禁用状态:控件不可用时的外观
+- 焦点状态:键盘导航时的焦点指示
+```
+
+## 动画和过渡
+
+### 动画设计原则
+- **有目的性**:动画应该有明确的功能目标
+- **自然性**:模拟真实世界的物理规律
+- **一致性**:整个应用中保持动画风格一致
+- **性能考虑**:避免影响应用性能的复杂动画
+
+### 缓动函数选择
+```
+常用缓动函数:
+- ease-in:慢开始,适合元素消失
+- ease-out:慢结束,适合元素出现
+- ease-in-out:慢开始慢结束,适合状态转换
+- linear:匀速,适合循环动画
+```
+
+### 动画时长建议
+```
+动画时长指南:
+- 微交互:100-200ms (按钮点击反馈)
+- 小元素:200-300ms (工具提示显示)
+- 中等元素:300-500ms (对话框打开)
+- 大元素:500-800ms (页面切换)
+- 复杂动画:800ms+ (数据可视化)
+```
+
+## 响应式设计
+
+### 断点设计
+```
+常用断点:
+- 手机:320-768px
+- 平板:768-1024px
+- 桌面:1024px+
+- 大屏:1440px+
+```
+
+### 自适应策略
+- **流式布局**:使用百分比而非固定像素
+- **弹性图片**:图片随容器大小缩放
+- **媒体查询**:针对不同屏幕尺寸应用不同样式
+- **移动优先**:从小屏幕开始设计,逐步增强
+
+## 可访问性设计
+
+### 键盘导航
+- **Tab顺序**:确保逻辑的Tab键导航顺序
+- **焦点指示**:清晰的焦点视觉指示
+- **快捷键**:为常用功能提供键盘快捷键
+
+### 屏幕阅读器支持
+- **语义化标签**:使用正确的HTML语义
+- **Alt文本**:为图片提供描述性文本
+- **标题层次**:正确的标题层次结构
+
+## 设计系统构建
+
+### 组件库设计
+```
+基础组件:
+- 按钮 (Button)
+- 输入框 (Input)
+- 选择器 (Select)
+- 复选框 (Checkbox)
+- 单选框 (Radio)
+```
+
+### 设计令牌 (Design Tokens)
+```
+颜色令牌:
+- primary-color: #4CAF50
+- secondary-color: #2196F3
+- success-color: #4CAF50
+- warning-color: #FF9800
+- error-color: #F44336
+
+间距令牌:
+- space-xs: 4px
+- space-sm: 8px
+- space-md: 16px
+- space-lg: 24px
+- space-xl: 32px
+```
diff --git a/.promptx/resource/domain/qt-ui-optimizer/qt-ui-optimizer.role.md b/.promptx/resource/domain/qt-ui-optimizer/qt-ui-optimizer.role.md
new file mode 100644
index 00000000..ee201b73
--- /dev/null
+++ b/.promptx/resource/domain/qt-ui-optimizer/qt-ui-optimizer.role.md
@@ -0,0 +1,19 @@
+
+
+ @!thought://remember
+ @!thought://recall
+ @!thought://ui-design-thinking
+ @!thought://academic-standards-awareness
+
+
+
+ @!execution://qt-optimization-workflow
+ @!execution://academic-ui-standards
+
+
+
+ @!knowledge://qt-ui-development
+ @!knowledge://ui-ux-principles
+ @!knowledge://academic-project-standards
+
+
diff --git a/.promptx/resource/domain/qt-ui-optimizer/thought/academic-standards-awareness.thought.md b/.promptx/resource/domain/qt-ui-optimizer/thought/academic-standards-awareness.thought.md
new file mode 100644
index 00000000..cd12e110
--- /dev/null
+++ b/.promptx/resource/domain/qt-ui-optimizer/thought/academic-standards-awareness.thought.md
@@ -0,0 +1,97 @@
+
+
+ ## 学术项目界面评分维度探索
+
+ ### 老师评分关注点
+ - **功能完整性**:所有要求功能是否都有对应界面?
+ - **专业美观度**:界面是否体现学生的技术水平?
+ - **用户体验**:操作是否直观、流畅、符合逻辑?
+ - **技术深度**:是否运用了课程所学的高级技术?
+ - **创新亮点**:是否有超出基本要求的设计创新?
+
+ ### 学术项目界面特殊要求
+ - **演示效果**:界面需要在课堂演示中给人深刻印象
+ - **功能展示**:核心技术点需要通过界面清晰展现
+ - **文档配合**:界面设计需要与技术文档相呼应
+ - **团队协作体现**:界面需要体现团队分工和协作成果
+
+ ### 与商业项目的差异
+ - **评分导向**:优先考虑评分标准而非市场需求
+ - **技术展示**:需要突出技术实现的复杂度和深度
+ - **学术规范**:遵循学术项目的严谨性和规范性
+ - **时间约束**:在有限时间内达到最佳展示效果
+
+
+
+ ## 学术标准对齐策略
+
+ ### 评分权重分析
+ ```
+ 学术项目界面评分构成:
+ 功能完整性 (30%) + 技术深度 (25%) + 美观专业度 (20%) +
+ 用户体验 (15%) + 创新亮点 (10%)
+ ```
+
+ ### 差异化竞争策略
+ - **技术深度体现**:通过复杂的QSS样式展现CSS功底
+ - **现代化设计**:采用当前流行的UI设计趋势
+ - **交互创新**:实现同学中少见的交互效果
+ - **细节打磨**:在细节处体现工程师的专业素养
+
+ ### 老师印象管理
+ - **第一印象**:界面启动后的第一屏要给人专业感
+ - **功能演示**:关键功能的界面要便于课堂演示
+ - **技术亮点**:将技术难点通过界面直观展现
+ - **完整性体现**:确保没有明显的界面缺陷或未完成感
+
+
+
+ ## 学术标准质疑
+
+ ### 评分标准的主观性
+ - 不同老师对界面美观的标准是否一致?
+ - 如何平衡技术展示与用户体验?
+ - 创新与稳定性之间如何取舍?
+
+ ### 时间成本考量
+ - 界面优化的投入产出比是否合理?
+ - 是否应该优先保证功能实现?
+ - 美化工作是否会影响其他模块开发?
+
+ ### 技术实现风险
+ - 复杂的界面设计是否会引入新的bug?
+ - 是否有足够的技术能力实现设计方案?
+ - 跨平台兼容性是否会成为问题?
+
+
+
+ ## 学术标准执行计划
+
+ ### 评分优化路径
+ ```mermaid
+ graph TD
+ A[基础功能界面] --> B[专业美观提升]
+ B --> C[用户体验优化]
+ C --> D[技术亮点添加]
+ D --> E[创新特性实现]
+ E --> F[细节完善]
+ F --> G[演示准备]
+ ```
+
+ ### 风险控制策略
+ ```mermaid
+ flowchart LR
+ A[设计方案] --> B{技术风险评估}
+ B -->|低风险| C[直接实施]
+ B -->|中风险| D[分阶段实施]
+ B -->|高风险| E[备选方案]
+ C --> F[效果验证]
+ D --> F
+ E --> F
+ F --> G{满足学术标准?}
+ G -->|是| H[完成]
+ G -->|否| I[调整优化]
+ I --> A
+ ```
+
+
diff --git a/.promptx/resource/domain/qt-ui-optimizer/thought/ui-design-thinking.thought.md b/.promptx/resource/domain/qt-ui-optimizer/thought/ui-design-thinking.thought.md
new file mode 100644
index 00000000..ac9c4f1c
--- /dev/null
+++ b/.promptx/resource/domain/qt-ui-optimizer/thought/ui-design-thinking.thought.md
@@ -0,0 +1,103 @@
+
+
+ ## UI设计问题探索
+
+ ### 界面美观度分析维度
+ - **视觉层次**:信息的重要性是否通过视觉元素清晰表达?
+ - **色彩搭配**:配色方案是否协调、专业、符合应用场景?
+ - **字体排版**:字体选择、大小、行距是否提升可读性?
+ - **空间布局**:元素间距、对齐、分组是否合理?
+ - **控件美化**:按钮、输入框、列表等控件是否现代化?
+
+ ### 用户体验痛点识别
+ - **操作流程**:用户完成任务的路径是否最短最直观?
+ - **反馈机制**:用户操作是否有及时、清晰的反馈?
+ - **错误处理**:异常情况下的提示和引导是否友好?
+ - **响应性能**:界面响应速度是否影响用户体验?
+ - **一致性**:整个应用的交互模式是否统一?
+
+ ### 学术项目特殊考量
+ - **专业度体现**:界面是否体现技术水平和工程素养?
+ - **功能展示**:核心功能是否得到突出展现?
+ - **创新亮点**:是否有设计创新点能获得加分?
+ - **完整性**:界面是否覆盖所有必要功能模块?
+
+
+
+ ## UI优化决策逻辑
+
+ ### 优先级评估框架
+ ```
+ 影响因素权重分析:
+ 学术评分影响 (40%) > 用户体验提升 (35%) > 技术实现难度 (25%)
+ ```
+
+ ### 美观度提升策略
+ - **现代化设计语言**:采用Material Design或Fluent Design原则
+ - **色彩心理学应用**:根据应用类型选择合适的主色调
+ - **视觉层次构建**:通过大小、颜色、位置建立信息层次
+ - **微交互设计**:添加适度的动画和过渡效果
+
+ ### 学术标准对齐策略
+ - **功能完整性优先**:确保所有要求功能都有清晰的界面入口
+ - **专业性体现**:通过精致的界面设计展现技术实力
+ - **创新点突出**:在界面设计中体现技术创新和思考深度
+ - **文档化设计**:为设计决策提供理论依据和说明
+
+
+
+ ## 设计决策质疑
+
+ ### 美观与功能的平衡
+ - 过度美化是否会影响功能的清晰表达?
+ - 动画效果是否会影响界面响应性能?
+ - 个性化设计是否符合学术项目的严肃性?
+
+ ### 技术实现的可行性
+ - 设计方案在Qt 5.15中是否都能实现?
+ - 复杂的QSS样式是否会影响维护性?
+ - 跨平台兼容性是否得到充分考虑?
+
+ ### 用户认知负载
+ - 界面元素是否过多造成认知负担?
+ - 交互模式是否符合用户习惯?
+ - 学习成本是否在可接受范围内?
+
+
+
+ ## UI设计思维流程
+
+ ### 分析阶段思维导图
+ ```mermaid
+ mindmap
+ root((界面分析))
+ 现状评估
+ 美观度评分
+ 用户体验痛点
+ 技术债务识别
+ 目标设定
+ 学术评分目标
+ 用户体验目标
+ 技术实现目标
+ 约束条件
+ 技术栈限制
+ 时间成本
+ 维护复杂度
+ ```
+
+ ### 设计决策流程
+ ```mermaid
+ flowchart TD
+ A[问题识别] --> B{影响评估}
+ B -->|高影响| C[优先解决]
+ B -->|中影响| D[计划解决]
+ B -->|低影响| E[暂缓处理]
+ C --> F[方案设计]
+ F --> G{技术可行性}
+ G -->|可行| H[实施方案]
+ G -->|不可行| I[替代方案]
+ H --> J[效果验证]
+ I --> J
+ ```
+
+
diff --git a/.promptx/resource/project.registry.json b/.promptx/resource/project.registry.json
index 60b09873..98307e69 100644
--- a/.promptx/resource/project.registry.json
+++ b/.promptx/resource/project.registry.json
@@ -4,9 +4,9 @@
"metadata": {
"version": "2.0.0",
"description": "project 级资源注册表",
- "createdAt": "2025-07-01T06:27:21.975Z",
- "updatedAt": "2025-07-01T06:27:21.978Z",
- "resourceCount": 32
+ "createdAt": "2025-07-03T12:28:21.053Z",
+ "updatedAt": "2025-07-03T12:28:21.059Z",
+ "resourceCount": 40
},
"resources": [
{
@@ -17,9 +17,9 @@
"description": "专业角色,提供特定领域的专业能力",
"reference": "@project://.promptx/resource/domain/course-project-writer/course-project-writer.role.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.976Z",
- "updatedAt": "2025-07-01T06:27:21.976Z",
- "scannedAt": "2025-07-01T06:27:21.976Z"
+ "createdAt": "2025-07-03T12:28:21.054Z",
+ "updatedAt": "2025-07-03T12:28:21.054Z",
+ "scannedAt": "2025-07-03T12:28:21.054Z"
}
},
{
@@ -30,9 +30,9 @@
"description": "思维模式,指导AI的思考方式",
"reference": "@project://.promptx/resource/domain/course-project-writer/thought/academic-writing.thought.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.976Z",
- "updatedAt": "2025-07-01T06:27:21.976Z",
- "scannedAt": "2025-07-01T06:27:21.976Z"
+ "createdAt": "2025-07-03T12:28:21.054Z",
+ "updatedAt": "2025-07-03T12:28:21.054Z",
+ "scannedAt": "2025-07-03T12:28:21.054Z"
}
},
{
@@ -43,9 +43,9 @@
"description": "思维模式,指导AI的思考方式",
"reference": "@project://.promptx/resource/domain/course-project-writer/thought/project-reflection.thought.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.976Z",
- "updatedAt": "2025-07-01T06:27:21.976Z",
- "scannedAt": "2025-07-01T06:27:21.976Z"
+ "createdAt": "2025-07-03T12:28:21.054Z",
+ "updatedAt": "2025-07-03T12:28:21.054Z",
+ "scannedAt": "2025-07-03T12:28:21.054Z"
}
},
{
@@ -56,9 +56,9 @@
"description": "执行模式,定义具体的行为模式",
"reference": "@project://.promptx/resource/domain/course-project-writer/execution/academic-report-writing.execution.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.976Z",
- "updatedAt": "2025-07-01T06:27:21.976Z",
- "scannedAt": "2025-07-01T06:27:21.976Z"
+ "createdAt": "2025-07-03T12:28:21.055Z",
+ "updatedAt": "2025-07-03T12:28:21.055Z",
+ "scannedAt": "2025-07-03T12:28:21.055Z"
}
},
{
@@ -69,9 +69,9 @@
"description": "执行模式,定义具体的行为模式",
"reference": "@project://.promptx/resource/domain/course-project-writer/execution/grade-optimization.execution.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.976Z",
- "updatedAt": "2025-07-01T06:27:21.976Z",
- "scannedAt": "2025-07-01T06:27:21.976Z"
+ "createdAt": "2025-07-03T12:28:21.055Z",
+ "updatedAt": "2025-07-03T12:28:21.055Z",
+ "scannedAt": "2025-07-03T12:28:21.055Z"
}
},
{
@@ -82,9 +82,9 @@
"description": "知识库,提供专业知识和信息",
"reference": "@project://.promptx/resource/domain/course-project-writer/knowledge/software-engineering-education.knowledge.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.976Z",
- "updatedAt": "2025-07-01T06:27:21.976Z",
- "scannedAt": "2025-07-01T06:27:21.976Z"
+ "createdAt": "2025-07-03T12:28:21.055Z",
+ "updatedAt": "2025-07-03T12:28:21.055Z",
+ "scannedAt": "2025-07-03T12:28:21.055Z"
}
},
{
@@ -95,9 +95,9 @@
"description": "知识库,提供专业知识和信息",
"reference": "@project://.promptx/resource/domain/course-project-writer/knowledge/technical-documentation.knowledge.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.976Z",
- "updatedAt": "2025-07-01T06:27:21.976Z",
- "scannedAt": "2025-07-01T06:27:21.976Z"
+ "createdAt": "2025-07-03T12:28:21.055Z",
+ "updatedAt": "2025-07-03T12:28:21.055Z",
+ "scannedAt": "2025-07-03T12:28:21.055Z"
}
},
{
@@ -108,9 +108,9 @@
"description": "专业角色,提供特定领域的专业能力",
"reference": "@project://.promptx/resource/domain/project-explainer/project-explainer.role.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.977Z",
- "updatedAt": "2025-07-01T06:27:21.977Z",
- "scannedAt": "2025-07-01T06:27:21.977Z"
+ "createdAt": "2025-07-03T12:28:21.055Z",
+ "updatedAt": "2025-07-03T12:28:21.055Z",
+ "scannedAt": "2025-07-03T12:28:21.055Z"
}
},
{
@@ -121,9 +121,9 @@
"description": "思维模式,指导AI的思考方式",
"reference": "@project://.promptx/resource/domain/project-explainer/thought/educational-guidance.thought.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.977Z",
- "updatedAt": "2025-07-01T06:27:21.977Z",
- "scannedAt": "2025-07-01T06:27:21.977Z"
+ "createdAt": "2025-07-03T12:28:21.055Z",
+ "updatedAt": "2025-07-03T12:28:21.055Z",
+ "scannedAt": "2025-07-03T12:28:21.055Z"
}
},
{
@@ -134,9 +134,9 @@
"description": "思维模式,指导AI的思考方式",
"reference": "@project://.promptx/resource/domain/project-explainer/thought/project-analysis.thought.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.977Z",
- "updatedAt": "2025-07-01T06:27:21.977Z",
- "scannedAt": "2025-07-01T06:27:21.977Z"
+ "createdAt": "2025-07-03T12:28:21.055Z",
+ "updatedAt": "2025-07-03T12:28:21.055Z",
+ "scannedAt": "2025-07-03T12:28:21.055Z"
}
},
{
@@ -147,9 +147,9 @@
"description": "执行模式,定义具体的行为模式",
"reference": "@project://.promptx/resource/domain/project-explainer/execution/academic-presentation.execution.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.977Z",
- "updatedAt": "2025-07-01T06:27:21.977Z",
- "scannedAt": "2025-07-01T06:27:21.977Z"
+ "createdAt": "2025-07-03T12:28:21.055Z",
+ "updatedAt": "2025-07-03T12:28:21.055Z",
+ "scannedAt": "2025-07-03T12:28:21.055Z"
}
},
{
@@ -160,9 +160,9 @@
"description": "执行模式,定义具体的行为模式",
"reference": "@project://.promptx/resource/domain/project-explainer/execution/project-explanation-workflow.execution.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.977Z",
- "updatedAt": "2025-07-01T06:27:21.977Z",
- "scannedAt": "2025-07-01T06:27:21.977Z"
+ "createdAt": "2025-07-03T12:28:21.055Z",
+ "updatedAt": "2025-07-03T12:28:21.055Z",
+ "scannedAt": "2025-07-03T12:28:21.055Z"
}
},
{
@@ -173,9 +173,9 @@
"description": "知识库,提供专业知识和信息",
"reference": "@project://.promptx/resource/domain/project-explainer/knowledge/academic-evaluation-standards.knowledge.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.977Z",
- "updatedAt": "2025-07-01T06:27:21.977Z",
- "scannedAt": "2025-07-01T06:27:21.977Z"
+ "createdAt": "2025-07-03T12:28:21.055Z",
+ "updatedAt": "2025-07-03T12:28:21.055Z",
+ "scannedAt": "2025-07-03T12:28:21.055Z"
}
},
{
@@ -186,9 +186,9 @@
"description": "知识库,提供专业知识和信息",
"reference": "@project://.promptx/resource/domain/project-explainer/knowledge/code-analysis-techniques.knowledge.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.977Z",
- "updatedAt": "2025-07-01T06:27:21.977Z",
- "scannedAt": "2025-07-01T06:27:21.977Z"
+ "createdAt": "2025-07-03T12:28:21.055Z",
+ "updatedAt": "2025-07-03T12:28:21.055Z",
+ "scannedAt": "2025-07-03T12:28:21.055Z"
}
},
{
@@ -199,9 +199,9 @@
"description": "知识库,提供专业知识和信息",
"reference": "@project://.promptx/resource/domain/project-explainer/knowledge/qt-architecture.knowledge.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.977Z",
- "updatedAt": "2025-07-01T06:27:21.977Z",
- "scannedAt": "2025-07-01T06:27:21.977Z"
+ "createdAt": "2025-07-03T12:28:21.055Z",
+ "updatedAt": "2025-07-03T12:28:21.055Z",
+ "scannedAt": "2025-07-03T12:28:21.055Z"
}
},
{
@@ -212,9 +212,9 @@
"description": "专业角色,提供特定领域的专业能力",
"reference": "@project://.promptx/resource/domain/project-poster-designer/project-poster-designer.role.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.977Z",
- "updatedAt": "2025-07-01T06:27:21.977Z",
- "scannedAt": "2025-07-01T06:27:21.977Z"
+ "createdAt": "2025-07-03T12:28:21.055Z",
+ "updatedAt": "2025-07-03T12:28:21.055Z",
+ "scannedAt": "2025-07-03T12:28:21.055Z"
}
},
{
@@ -225,9 +225,9 @@
"description": "思维模式,指导AI的思考方式",
"reference": "@project://.promptx/resource/domain/project-poster-designer/thought/creative-thinking.thought.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.977Z",
- "updatedAt": "2025-07-01T06:27:21.977Z",
- "scannedAt": "2025-07-01T06:27:21.977Z"
+ "createdAt": "2025-07-03T12:28:21.056Z",
+ "updatedAt": "2025-07-03T12:28:21.056Z",
+ "scannedAt": "2025-07-03T12:28:21.056Z"
}
},
{
@@ -238,9 +238,9 @@
"description": "思维模式,指导AI的思考方式",
"reference": "@project://.promptx/resource/domain/project-poster-designer/thought/visual-design.thought.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.977Z",
- "updatedAt": "2025-07-01T06:27:21.977Z",
- "scannedAt": "2025-07-01T06:27:21.977Z"
+ "createdAt": "2025-07-03T12:28:21.056Z",
+ "updatedAt": "2025-07-03T12:28:21.056Z",
+ "scannedAt": "2025-07-03T12:28:21.056Z"
}
},
{
@@ -251,9 +251,9 @@
"description": "执行模式,定义具体的行为模式",
"reference": "@project://.promptx/resource/domain/project-poster-designer/execution/poster-design-process.execution.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.977Z",
- "updatedAt": "2025-07-01T06:27:21.977Z",
- "scannedAt": "2025-07-01T06:27:21.977Z"
+ "createdAt": "2025-07-03T12:28:21.056Z",
+ "updatedAt": "2025-07-03T12:28:21.056Z",
+ "scannedAt": "2025-07-03T12:28:21.056Z"
}
},
{
@@ -264,9 +264,9 @@
"description": "执行模式,定义具体的行为模式",
"reference": "@project://.promptx/resource/domain/project-poster-designer/execution/visual-communication.execution.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.977Z",
- "updatedAt": "2025-07-01T06:27:21.977Z",
- "scannedAt": "2025-07-01T06:27:21.977Z"
+ "createdAt": "2025-07-03T12:28:21.056Z",
+ "updatedAt": "2025-07-03T12:28:21.056Z",
+ "scannedAt": "2025-07-03T12:28:21.056Z"
}
},
{
@@ -277,9 +277,9 @@
"description": "知识库,提供专业知识和信息",
"reference": "@project://.promptx/resource/domain/project-poster-designer/knowledge/graphic-design.knowledge.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.978Z",
- "updatedAt": "2025-07-01T06:27:21.978Z",
- "scannedAt": "2025-07-01T06:27:21.978Z"
+ "createdAt": "2025-07-03T12:28:21.056Z",
+ "updatedAt": "2025-07-03T12:28:21.056Z",
+ "scannedAt": "2025-07-03T12:28:21.056Z"
}
},
{
@@ -290,9 +290,9 @@
"description": "知识库,提供专业知识和信息",
"reference": "@project://.promptx/resource/domain/project-poster-designer/knowledge/military-tech-aesthetics.knowledge.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.978Z",
- "updatedAt": "2025-07-01T06:27:21.978Z",
- "scannedAt": "2025-07-01T06:27:21.978Z"
+ "createdAt": "2025-07-03T12:28:21.056Z",
+ "updatedAt": "2025-07-03T12:28:21.056Z",
+ "scannedAt": "2025-07-03T12:28:21.056Z"
}
},
{
@@ -303,9 +303,9 @@
"description": "知识库,提供专业知识和信息",
"reference": "@project://.promptx/resource/domain/project-poster-designer/knowledge/project-presentation.knowledge.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.978Z",
- "updatedAt": "2025-07-01T06:27:21.978Z",
- "scannedAt": "2025-07-01T06:27:21.978Z"
+ "createdAt": "2025-07-03T12:28:21.056Z",
+ "updatedAt": "2025-07-03T12:28:21.056Z",
+ "scannedAt": "2025-07-03T12:28:21.056Z"
}
},
{
@@ -316,9 +316,9 @@
"description": "专业角色,提供特定领域的专业能力",
"reference": "@project://.promptx/resource/domain/qt-code-optimizer/qt-code-optimizer.role.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.978Z",
- "updatedAt": "2025-07-01T06:27:21.978Z",
- "scannedAt": "2025-07-01T06:27:21.978Z"
+ "createdAt": "2025-07-03T12:28:21.057Z",
+ "updatedAt": "2025-07-03T12:28:21.057Z",
+ "scannedAt": "2025-07-03T12:28:21.057Z"
}
},
{
@@ -329,9 +329,9 @@
"description": "思维模式,指导AI的思考方式",
"reference": "@project://.promptx/resource/domain/qt-code-optimizer/thought/qt-code-analysis.thought.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.978Z",
- "updatedAt": "2025-07-01T06:27:21.978Z",
- "scannedAt": "2025-07-01T06:27:21.978Z"
+ "createdAt": "2025-07-03T12:28:21.057Z",
+ "updatedAt": "2025-07-03T12:28:21.057Z",
+ "scannedAt": "2025-07-03T12:28:21.057Z"
}
},
{
@@ -342,9 +342,9 @@
"description": "思维模式,指导AI的思考方式",
"reference": "@project://.promptx/resource/domain/qt-code-optimizer/thought/quality-assessment.thought.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.978Z",
- "updatedAt": "2025-07-01T06:27:21.978Z",
- "scannedAt": "2025-07-01T06:27:21.978Z"
+ "createdAt": "2025-07-03T12:28:21.057Z",
+ "updatedAt": "2025-07-03T12:28:21.057Z",
+ "scannedAt": "2025-07-03T12:28:21.057Z"
}
},
{
@@ -355,9 +355,9 @@
"description": "执行模式,定义具体的行为模式",
"reference": "@project://.promptx/resource/domain/qt-code-optimizer/execution/academic-standards.execution.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.978Z",
- "updatedAt": "2025-07-01T06:27:21.978Z",
- "scannedAt": "2025-07-01T06:27:21.978Z"
+ "createdAt": "2025-07-03T12:28:21.057Z",
+ "updatedAt": "2025-07-03T12:28:21.057Z",
+ "scannedAt": "2025-07-03T12:28:21.057Z"
}
},
{
@@ -368,9 +368,9 @@
"description": "执行模式,定义具体的行为模式",
"reference": "@project://.promptx/resource/domain/qt-code-optimizer/execution/qt-code-optimization.execution.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.978Z",
- "updatedAt": "2025-07-01T06:27:21.978Z",
- "scannedAt": "2025-07-01T06:27:21.978Z"
+ "createdAt": "2025-07-03T12:28:21.057Z",
+ "updatedAt": "2025-07-03T12:28:21.057Z",
+ "scannedAt": "2025-07-03T12:28:21.057Z"
}
},
{
@@ -381,9 +381,9 @@
"description": "执行模式,定义具体的行为模式",
"reference": "@project://.promptx/resource/domain/qt-code-optimizer/execution/quality-improvement.execution.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.978Z",
- "updatedAt": "2025-07-01T06:27:21.978Z",
- "scannedAt": "2025-07-01T06:27:21.978Z"
+ "createdAt": "2025-07-03T12:28:21.057Z",
+ "updatedAt": "2025-07-03T12:28:21.057Z",
+ "scannedAt": "2025-07-03T12:28:21.057Z"
}
},
{
@@ -394,9 +394,9 @@
"description": "知识库,提供专业知识和信息",
"reference": "@project://.promptx/resource/domain/qt-code-optimizer/knowledge/code-quality-standards.knowledge.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.978Z",
- "updatedAt": "2025-07-01T06:27:21.978Z",
- "scannedAt": "2025-07-01T06:27:21.978Z"
+ "createdAt": "2025-07-03T12:28:21.058Z",
+ "updatedAt": "2025-07-03T12:28:21.058Z",
+ "scannedAt": "2025-07-03T12:28:21.058Z"
}
},
{
@@ -407,9 +407,9 @@
"description": "知识库,提供专业知识和信息",
"reference": "@project://.promptx/resource/domain/qt-code-optimizer/knowledge/project-architecture.knowledge.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.978Z",
- "updatedAt": "2025-07-01T06:27:21.978Z",
- "scannedAt": "2025-07-01T06:27:21.978Z"
+ "createdAt": "2025-07-03T12:28:21.058Z",
+ "updatedAt": "2025-07-03T12:28:21.058Z",
+ "scannedAt": "2025-07-03T12:28:21.058Z"
}
},
{
@@ -420,22 +420,126 @@
"description": "知识库,提供专业知识和信息",
"reference": "@project://.promptx/resource/domain/qt-code-optimizer/knowledge/qt-cpp-expertise.knowledge.md",
"metadata": {
- "createdAt": "2025-07-01T06:27:21.978Z",
- "updatedAt": "2025-07-01T06:27:21.978Z",
- "scannedAt": "2025-07-01T06:27:21.978Z"
+ "createdAt": "2025-07-03T12:28:21.058Z",
+ "updatedAt": "2025-07-03T12:28:21.058Z",
+ "scannedAt": "2025-07-03T12:28:21.058Z"
+ }
+ },
+ {
+ "id": "qt-ui-optimizer",
+ "source": "project",
+ "protocol": "role",
+ "name": "Qt Ui Optimizer 角色",
+ "description": "专业角色,提供特定领域的专业能力",
+ "reference": "@project://.promptx/resource/domain/qt-ui-optimizer/qt-ui-optimizer.role.md",
+ "metadata": {
+ "createdAt": "2025-07-03T12:28:21.058Z",
+ "updatedAt": "2025-07-03T12:28:21.058Z",
+ "scannedAt": "2025-07-03T12:28:21.058Z"
+ }
+ },
+ {
+ "id": "academic-standards-awareness",
+ "source": "project",
+ "protocol": "thought",
+ "name": "Academic Standards Awareness 思维模式",
+ "description": "思维模式,指导AI的思考方式",
+ "reference": "@project://.promptx/resource/domain/qt-ui-optimizer/thought/academic-standards-awareness.thought.md",
+ "metadata": {
+ "createdAt": "2025-07-03T12:28:21.058Z",
+ "updatedAt": "2025-07-03T12:28:21.058Z",
+ "scannedAt": "2025-07-03T12:28:21.058Z"
+ }
+ },
+ {
+ "id": "ui-design-thinking",
+ "source": "project",
+ "protocol": "thought",
+ "name": "Ui Design Thinking 思维模式",
+ "description": "思维模式,指导AI的思考方式",
+ "reference": "@project://.promptx/resource/domain/qt-ui-optimizer/thought/ui-design-thinking.thought.md",
+ "metadata": {
+ "createdAt": "2025-07-03T12:28:21.058Z",
+ "updatedAt": "2025-07-03T12:28:21.058Z",
+ "scannedAt": "2025-07-03T12:28:21.058Z"
+ }
+ },
+ {
+ "id": "academic-ui-standards",
+ "source": "project",
+ "protocol": "execution",
+ "name": "Academic Ui Standards 执行模式",
+ "description": "执行模式,定义具体的行为模式",
+ "reference": "@project://.promptx/resource/domain/qt-ui-optimizer/execution/academic-ui-standards.execution.md",
+ "metadata": {
+ "createdAt": "2025-07-03T12:28:21.059Z",
+ "updatedAt": "2025-07-03T12:28:21.059Z",
+ "scannedAt": "2025-07-03T12:28:21.059Z"
+ }
+ },
+ {
+ "id": "qt-optimization-workflow",
+ "source": "project",
+ "protocol": "execution",
+ "name": "Qt Optimization Workflow 执行模式",
+ "description": "执行模式,定义具体的行为模式",
+ "reference": "@project://.promptx/resource/domain/qt-ui-optimizer/execution/qt-optimization-workflow.execution.md",
+ "metadata": {
+ "createdAt": "2025-07-03T12:28:21.059Z",
+ "updatedAt": "2025-07-03T12:28:21.059Z",
+ "scannedAt": "2025-07-03T12:28:21.059Z"
+ }
+ },
+ {
+ "id": "academic-project-standards",
+ "source": "project",
+ "protocol": "knowledge",
+ "name": "Academic Project Standards 知识库",
+ "description": "知识库,提供专业知识和信息",
+ "reference": "@project://.promptx/resource/domain/qt-ui-optimizer/knowledge/academic-project-standards.knowledge.md",
+ "metadata": {
+ "createdAt": "2025-07-03T12:28:21.059Z",
+ "updatedAt": "2025-07-03T12:28:21.059Z",
+ "scannedAt": "2025-07-03T12:28:21.059Z"
+ }
+ },
+ {
+ "id": "qt-ui-development",
+ "source": "project",
+ "protocol": "knowledge",
+ "name": "Qt Ui Development 知识库",
+ "description": "知识库,提供专业知识和信息",
+ "reference": "@project://.promptx/resource/domain/qt-ui-optimizer/knowledge/qt-ui-development.knowledge.md",
+ "metadata": {
+ "createdAt": "2025-07-03T12:28:21.059Z",
+ "updatedAt": "2025-07-03T12:28:21.059Z",
+ "scannedAt": "2025-07-03T12:28:21.059Z"
+ }
+ },
+ {
+ "id": "ui-ux-principles",
+ "source": "project",
+ "protocol": "knowledge",
+ "name": "Ui Ux Principles 知识库",
+ "description": "知识库,提供专业知识和信息",
+ "reference": "@project://.promptx/resource/domain/qt-ui-optimizer/knowledge/ui-ux-principles.knowledge.md",
+ "metadata": {
+ "createdAt": "2025-07-03T12:28:21.059Z",
+ "updatedAt": "2025-07-03T12:28:21.059Z",
+ "scannedAt": "2025-07-03T12:28:21.059Z"
}
}
],
"stats": {
- "totalResources": 32,
+ "totalResources": 40,
"byProtocol": {
- "role": 4,
- "thought": 8,
- "execution": 9,
- "knowledge": 11
+ "role": 5,
+ "thought": 10,
+ "execution": 11,
+ "knowledge": 14
},
"bySource": {
- "project": 32
+ "project": 40
}
}
}
diff --git a/doc/软件设计规格说明书.doc b/doc/软件设计规格说明书.doc
index 0298d441..4168790a 100644
Binary files a/doc/软件设计规格说明书.doc and b/doc/软件设计规格说明书.doc differ
diff --git a/facelightcontrol/CMakeLists2.txt b/facelightcontrol/CMakeLists2.txt
new file mode 100644
index 00000000..62e3e6a2
--- /dev/null
+++ b/facelightcontrol/CMakeLists2.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 2.14)
+project(faceLightClient2)
+
+set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -O3 -march=native -Wall")
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+include_directories(include)
+link_directories(lib)
+
+add_executable(faceLightClient2 main2.cpp)
+target_link_libraries(faceLightClient2 libfaceLight_SDK_arm64.so)
+
+set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
\ No newline at end of file
diff --git a/facelightcontrol/README_faceLight.md b/facelightcontrol/README_faceLight.md
new file mode 100644
index 00000000..343dee43
--- /dev/null
+++ b/facelightcontrol/README_faceLight.md
@@ -0,0 +1,112 @@
+# FaceLight 命令行控制工具
+
+## 编译方法
+
+```bash
+# 使用新的CMakeLists.txt编译
+mkdir build2
+cd build2
+cmake -f ../CMakeLists2.txt ..
+make
+
+# 编译完成后,可执行文件位于 bin/faceLightClient2
+```
+
+## 使用方法
+
+### 基本语法
+```bash
+./bin/faceLightClient2 [选项]
+```
+
+### 可用选项
+
+| 选项 | 长选项 | 参数 | 说明 |
+|------|--------|------|------|
+| -m | --mode | MODE | 控制模式:all\|single\|cycle\|custom\|pattern |
+| -c | --color | COLOR | 颜色:red\|green\|blue\|yellow\|white\|black |
+| -i | --index | INDEX | LED索引(0-11),用于single模式 |
+| -d | --delay | DELAY | 延时(毫秒),默认2000 |
+| -p | --pattern | PATTERN | 自定义图案:"0:red,1:green,2:blue" |
+| -t | --times | TIMES | 循环次数,默认无限 |
+| -h | --help | | 显示帮助信息 |
+
+### 控制模式说明
+
+#### 1. all - 全部LED同色
+所有LED使用相同颜色
+```bash
+./bin/faceLightClient2 -m all -c red # 全部LED红色
+./bin/faceLightClient2 -m all -c blue # 全部LED蓝色
+```
+
+#### 2. single - 单个LED控制
+控制指定索引的单个LED
+```bash
+./bin/faceLightClient2 -m single -i 0 -c red # LED 0 红色
+./bin/faceLightClient2 -m single -i 5 -c green # LED 5 绿色
+```
+
+#### 3. cycle - 颜色循环
+自动循环显示不同颜色
+```bash
+./bin/faceLightClient2 -m cycle # 无限循环
+./bin/faceLightClient2 -m cycle -t 3 # 循环3次
+./bin/faceLightClient2 -m cycle -d 1000 -t 5 # 每秒切换,循环5次
+```
+
+#### 4. custom - RGB交替模式
+原始示例程序的RGB交替模式
+```bash
+./bin/faceLightClient2 -m custom
+```
+
+#### 5. pattern - 自定义图案
+根据指定的图案设置不同LED
+```bash
+./bin/faceLightClient2 -m pattern -p "0:red,1:green,2:blue"
+./bin/faceLightClient2 -m pattern -p "0:red,5:green,10:blue"
+```
+
+### 使用示例
+
+```bash
+# 1. 查看帮助
+./bin/faceLightClient2 -h
+
+# 2. 设置所有LED为红色
+./bin/faceLightClient2 -m all -c red
+
+# 3. 设置第0个LED为蓝色(其他关闭)
+./bin/faceLightClient2 -m single -i 0 -c blue
+
+# 4. 颜色循环,每1秒切换一次,循环10次
+./bin/faceLightClient2 -m cycle -d 1000 -t 10
+
+# 5. 自定义图案:0号红色,3号绿色,6号蓝色
+./bin/faceLightClient2 -m pattern -p "0:red,3:green,6:blue"
+
+# 6. RGB交替模式
+./bin/faceLightClient2 -m custom
+```
+
+## LED索引说明
+
+机器狗面部LED索引范围:0-11
+- 具体的LED位置映射请参考硬件文档
+
+## 可用颜色
+
+- red(红色)
+- green(绿色)
+- blue(蓝色)
+- yellow(黄色)
+- white(白色)
+- black(黑色/关闭)
+
+## 注意事项
+
+1. 使用前确保已正确连接到机器狗系统
+2. 确保libfaceLight_SDK_arm64.so库文件在lib目录中
+3. 程序需要在机器狗系统上运行(ARM64架构)
+4. 设置颜色后需要调用sendCmd()函数才能生效(程序已自动处理)
\ No newline at end of file
diff --git a/facelightcontrol/main2.cpp b/facelightcontrol/main2.cpp
new file mode 100644
index 00000000..30ddb1e5
--- /dev/null
+++ b/facelightcontrol/main2.cpp
@@ -0,0 +1,210 @@
+#include "FaceLightClient.h"
+#include
+#include
+#include
+#include
-
- 6
+ 12
-
@@ -908,47 +886,7 @@ border-radius: 1px;
-
-
-
-
-
- 添加机器人
-
-
-
-
- 显示机器人
-
-
- <html><head/><body><p>显示机器人</p></body></html>
-
-
-
-
- 伤员
-
-
-
-
- 加载地图
-
-
+
diff --git a/src/Client/include/core/database/DatabaseConfig.h b/src/Client/include/core/database/DatabaseConfig.h
new file mode 100644
index 00000000..48d1d41d
--- /dev/null
+++ b/src/Client/include/core/database/DatabaseConfig.h
@@ -0,0 +1,157 @@
+/**
+ * @file DatabaseConfig.h
+ * @brief 数据库配置类头文件
+ * @author BattlefieldExplorationSystem Team
+ * @date 2024-01-01
+ * @version 2.0
+ */
+
+#ifndef DATABASECONFIG_H
+#define DATABASECONFIG_H
+
+#include
+#include
+
+/**
+ * @struct DatabaseConnectionInfo
+ * @brief 数据库连接信息结构体
+ */
+struct DatabaseConnectionInfo
+{
+ QString hostName; ///< 主机名
+ int port; ///< 端口
+ QString databaseName; ///< 数据库名
+ QString username; ///< 用户名
+ QString password; ///< 密码
+};
+
+/**
+ * @class DatabaseConfig
+ * @brief 数据库配置管理类
+ *
+ * 提供统一的数据库连接配置管理,包括连接参数、
+ * 连接池配置等功能。
+ */
+class DatabaseConfig
+{
+public:
+ /**
+ * @brief 获取单例实例
+ * @return DatabaseConfig实例指针
+ */
+ static DatabaseConfig* getInstance();
+
+ /**
+ * @brief 获取数据库主机地址
+ * @return 数据库主机地址
+ */
+ QString getHost() const;
+
+ /**
+ * @brief 获取数据库端口
+ * @return 数据库端口
+ */
+ int getPort() const;
+
+ /**
+ * @brief 获取数据库名称
+ * @return 数据库名称
+ */
+ QString getDatabaseName() const;
+
+ /**
+ * @brief 获取数据库用户名
+ * @return 数据库用户名
+ */
+ QString getUsername() const;
+
+ /**
+ * @brief 获取数据库密码
+ * @return 数据库密码
+ */
+ QString getPassword() const;
+
+ /**
+ * @brief 获取连接超时时间
+ * @return 连接超时时间(秒)
+ */
+ int getConnectTimeout() const;
+
+ /**
+ * @brief 获取最大连接数
+ * @return 最大连接数
+ */
+ int getMaxConnections() const;
+
+ /**
+ * @brief 设置数据库配置
+ * @param host 主机地址
+ * @param port 端口
+ * @param dbName 数据库名称
+ * @param username 用户名
+ * @param password 密码
+ */
+ void setDatabaseConfig(const QString& host, int port, const QString& dbName,
+ const QString& username, const QString& password);
+
+ /**
+ * @brief 加载配置文件
+ * @param configPath 配置文件路径
+ * @return 是否成功加载
+ */
+ bool loadConfig(const QString& configPath = "");
+
+ /**
+ * @brief 保存配置文件
+ * @param configPath 配置文件路径
+ * @return 是否成功保存
+ */
+ bool saveConfig(const QString& configPath = "");
+
+ /**
+ * @brief 获取数据库连接信息
+ * @return 数据库连接信息结构体
+ */
+ DatabaseConnectionInfo getConnectionInfo() const;
+
+private:
+ /**
+ * @brief 私有构造函数
+ */
+ DatabaseConfig();
+
+ /**
+ * @brief 私有析构函数
+ */
+ ~DatabaseConfig();
+
+ /**
+ * @brief 禁用拷贝构造函数
+ */
+ DatabaseConfig(const DatabaseConfig&) = delete;
+
+ /**
+ * @brief 禁用赋值操作符
+ */
+ DatabaseConfig& operator=(const DatabaseConfig&) = delete;
+
+ /**
+ * @brief 初始化默认配置
+ */
+ void initDefaultConfig();
+
+private:
+ static DatabaseConfig* m_instance; ///< 单例实例
+
+ QString m_host; ///< 数据库主机地址
+ int m_port; ///< 数据库端口
+ QString m_databaseName; ///< 数据库名称
+ QString m_username; ///< 数据库用户名
+ QString m_password; ///< 数据库密码
+ int m_connectTimeout; ///< 连接超时时间
+ int m_maxConnections; ///< 最大连接数
+
+ QSettings* m_settings; ///< 配置文件管理器
+};
+
+#endif // DATABASECONFIG_H
\ No newline at end of file
diff --git a/src/Client/include/core/database/DatabaseHelper.h b/src/Client/include/core/database/DatabaseHelper.h
new file mode 100644
index 00000000..79e651be
--- /dev/null
+++ b/src/Client/include/core/database/DatabaseHelper.h
@@ -0,0 +1,183 @@
+/**
+ * @file DatabaseHelper.h
+ * @brief 数据库助手类头文件
+ * @author BattlefieldExplorationSystem Team
+ * @date 2024-01-01
+ * @version 2.0
+ */
+
+#ifndef DATABASEHELPER_H
+#define DATABASEHELPER_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+/**
+ * @class DatabaseHelper
+ * @brief 数据库助手类
+ *
+ * 提供统一的数据库连接管理、连接池管理等功能。
+ * 支持多线程安全的数据库操作。
+ */
+class DatabaseHelper
+{
+public:
+ /**
+ * @brief 获取单例实例
+ * @return DatabaseHelper实例指针
+ */
+ static DatabaseHelper* getInstance();
+
+ /**
+ * @brief 创建数据库连接
+ * @param connectionName 连接名称,如果为空则自动生成
+ * @return QSqlDatabase对象
+ */
+ static QSqlDatabase createConnection(const QString& connectionName = "");
+
+ /**
+ * @brief 创建临时数据库连接
+ * @param connectionName 连接名称
+ * @return QSqlDatabase对象
+ */
+ static QSqlDatabase createTempConnection(const QString& connectionName);
+
+ /**
+ * @brief 关闭数据库连接
+ * @param connectionName 连接名称
+ */
+ static void closeConnection(const QString& connectionName);
+
+ /**
+ * @brief 关闭所有数据库连接
+ */
+ static void closeAllConnections();
+
+ /**
+ * @brief 检查数据库连接是否有效
+ * @param connectionName 连接名称
+ * @return 是否有效
+ */
+ static bool isConnectionValid(const QString& connectionName);
+
+ /**
+ * @brief 执行SQL查询
+ * @param query SQL查询语句
+ * @param connectionName 连接名称
+ * @return 查询结果
+ */
+ static QSqlQuery executeQuery(const QString& query, const QString& connectionName = "");
+
+ /**
+ * @brief 开始事务
+ * @param connectionName 连接名称
+ * @return 是否成功
+ */
+ static bool beginTransaction(const QString& connectionName = "");
+
+ /**
+ * @brief 提交事务
+ * @param connectionName 连接名称
+ * @return 是否成功
+ */
+ static bool commitTransaction(const QString& connectionName = "");
+
+ /**
+ * @brief 回滚事务
+ * @param connectionName 连接名称
+ * @return 是否成功
+ */
+ static bool rollbackTransaction(const QString& connectionName = "");
+
+ /**
+ * @brief 初始化数据库
+ * @return 是否成功
+ */
+ static bool initializeDatabase();
+
+ /**
+ * @brief 创建数据库表
+ * @return 是否成功
+ */
+ static bool createTables();
+
+ /**
+ * @brief 获取最后一个错误
+ * @param connectionName 连接名称
+ * @return 错误信息
+ */
+ static QString getLastError(const QString& connectionName = "");
+
+ /**
+ * @brief 测试数据库连接
+ * @return 是否连接成功
+ */
+ static bool testConnection();
+
+private:
+ /**
+ * @brief 私有构造函数
+ */
+ DatabaseHelper();
+
+ /**
+ * @brief 私有析构函数
+ */
+ ~DatabaseHelper();
+
+ /**
+ * @brief 禁用拷贝构造函数
+ */
+ DatabaseHelper(const DatabaseHelper&) = delete;
+
+ /**
+ * @brief 禁用赋值操作符
+ */
+ DatabaseHelper& operator=(const DatabaseHelper&) = delete;
+
+ /**
+ * @brief 生成唯一连接名称
+ * @return 连接名称
+ */
+ static QString generateConnectionName();
+
+ /**
+ * @brief 配置数据库连接
+ * @param db 数据库连接对象
+ * @return 是否成功
+ */
+ static bool configureConnection(QSqlDatabase& db);
+
+ /**
+ * @brief 创建设备表
+ * @param db 数据库连接
+ * @return 是否成功
+ */
+ static bool createDevicesTable(QSqlDatabase& db);
+
+ /**
+ * @brief 创建操作日志表
+ * @param db 数据库连接
+ * @return 是否成功
+ */
+ static bool createOperationLogsTable(QSqlDatabase& db);
+
+ /**
+ * @brief 创建系统配置表
+ * @param db 数据库连接
+ * @return 是否成功
+ */
+ static bool createSystemConfigTable(QSqlDatabase& db);
+
+private:
+ static DatabaseHelper* m_instance; ///< 单例实例
+ static QMutex m_mutex; ///< 线程安全锁
+ static QMap m_connections; ///< 连接池
+ static int m_connectionCounter; ///< 连接计数器
+};
+
+#endif // DATABASEHELPER_H
\ No newline at end of file
diff --git a/src/Client/include/core/database/DatabaseManager.h b/src/Client/include/core/database/DatabaseManager.h
new file mode 100644
index 00000000..f4a1db0e
--- /dev/null
+++ b/src/Client/include/core/database/DatabaseManager.h
@@ -0,0 +1,350 @@
+/**
+ * @file DatabaseManager.h
+ * @brief 数据库连接管理器 - RAII模式实现
+ * @author BattlefieldExplorationSystem Team
+ * @date 2024-01-01
+ * @version 2.0
+ *
+ * 现代化的数据库连接管理器,特性:
+ * - RAII自动资源管理
+ * - 连接池支持
+ * - 线程安全的连接获取
+ * - 自动重连机制
+ * - 安全的配置管理集成
+ *
+ * @note 替代硬编码的数据库连接,提供统一的数据库访问接口
+ * @since 2.0
+ */
+
+#ifndef DATABASEMANAGER_H
+#define DATABASEMANAGER_H
+
+// C++标准库头文件
+#include
+#include
+#include
+#include
+#include
+
+// Qt头文件
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// 前向声明
+class ConfigManager;
+
+/**
+ * @class DatabaseConnection
+ * @brief RAII风格的数据库连接包装器
+ *
+ * 自动管理数据库连接的生命周期,确保连接在超出作用域时自动释放。
+ *
+ * 特性:
+ * - 自动连接管理
+ * - 异常安全
+ * - 移动语义支持
+ * - 自动重连
+ *
+ * @since 2.0
+ */
+class DatabaseConnection
+{
+public:
+ /**
+ * @brief 构造函数 - 自动建立连接
+ * @param connectionName 连接名称
+ * @param autoReconnect 是否启用自动重连
+ */
+ explicit DatabaseConnection(const QString& connectionName, bool autoReconnect = true);
+
+ /**
+ * @brief 析构函数 - 自动释放连接
+ */
+ ~DatabaseConnection();
+
+ // 禁用拷贝构造和拷贝赋值
+ DatabaseConnection(const DatabaseConnection&) = delete;
+ DatabaseConnection& operator=(const DatabaseConnection&) = delete;
+
+ // 支持移动语义
+ DatabaseConnection(DatabaseConnection&& other) noexcept;
+ DatabaseConnection& operator=(DatabaseConnection&& other) noexcept;
+
+ /**
+ * @brief 检查连接是否有效
+ * @return bool 连接状态
+ */
+ bool isValid() const;
+
+ /**
+ * @brief 获取数据库对象
+ * @return QSqlDatabase& 数据库引用
+ * @throws std::runtime_error 如果连接无效
+ */
+ QSqlDatabase& database();
+
+ /**
+ * @brief 获取数据库对象(只读)
+ * @return const QSqlDatabase& 数据库引用
+ * @throws std::runtime_error 如果连接无效
+ */
+ const QSqlDatabase& database() const;
+
+ /**
+ * @brief 执行SQL查询
+ * @param sql SQL语句
+ * @return std::unique_ptr 查询对象
+ */
+ std::unique_ptr executeQuery(const QString& sql);
+
+ /**
+ * @brief 执行预编译查询
+ * @param sql SQL语句
+ * @param bindings 绑定参数
+ * @return std::unique_ptr 查询对象
+ */
+ std::unique_ptr executePreparedQuery(const QString& sql,
+ const QVariantList& bindings = QVariantList());
+
+ /**
+ * @brief 开始事务
+ * @return bool 是否成功
+ */
+ bool beginTransaction();
+
+ /**
+ * @brief 提交事务
+ * @return bool 是否成功
+ */
+ bool commitTransaction();
+
+ /**
+ * @brief 回滚事务
+ * @return bool 是否成功
+ */
+ bool rollbackTransaction();
+
+ /**
+ * @brief 获取最后的错误信息
+ * @return QSqlError 错误信息
+ */
+ QSqlError lastError() const;
+
+private:
+ /**
+ * @brief 尝试重新连接
+ * @return bool 重连是否成功
+ */
+ bool reconnect();
+
+private:
+ QString m_connectionName; ///< 连接名称
+ QSqlDatabase m_database; ///< 数据库对象
+ bool m_autoReconnect; ///< 是否自动重连
+ bool m_isValid; ///< 连接状态
+};
+
+/**
+ * @class DatabaseManager
+ * @brief 数据库连接池管理器
+ *
+ * 线程安全的数据库连接管理器,提供连接池功能和统一的数据库访问接口。
+ *
+ * 主要功能:
+ * - 连接池管理
+ * - 自动配置加载
+ * - 健康检查
+ * - 统计信息
+ *
+ * @note 单例模式实现,确保全局统一的数据库管理
+ * @since 2.0
+ */
+class DatabaseManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ /**
+ * @brief 获取数据库管理器单例
+ * @return DatabaseManager& 单例引用
+ */
+ static DatabaseManager& getInstance();
+
+ /**
+ * @brief 析构函数
+ */
+ ~DatabaseManager() override;
+
+ // 禁用拷贝和移动
+ DatabaseManager(const DatabaseManager&) = delete;
+ DatabaseManager& operator=(const DatabaseManager&) = delete;
+ DatabaseManager(DatabaseManager&&) = delete;
+ DatabaseManager& operator=(DatabaseManager&&) = delete;
+
+ /**
+ * @brief 初始化数据库管理器
+ * @param maxConnections 最大连接数
+ * @return bool 初始化是否成功
+ */
+ bool initialize(int maxConnections = 10);
+
+ /**
+ * @brief 获取数据库连接
+ * @param connectionName 连接名称(可选)
+ * @return std::unique_ptr 连接对象
+ */
+ std::unique_ptr getConnection(const QString& connectionName = QString());
+
+ /**
+ * @brief 测试数据库连接
+ * @return bool 连接是否可用
+ */
+ bool testConnection();
+
+ /**
+ * @brief 获取连接池统计信息
+ * @return QString 统计信息
+ */
+ QString getPoolStatistics() const;
+
+ /**
+ * @brief 关闭所有连接
+ */
+ void closeAllConnections();
+
+ /**
+ * @brief 检查数据库是否可用
+ * @return bool 可用状态
+ */
+ bool isDatabaseAvailable() const;
+
+public slots:
+ /**
+ * @brief 执行连接健康检查
+ */
+ void performHealthCheck();
+
+ /**
+ * @brief 清理超时连接
+ */
+ void cleanupIdleConnections();
+
+signals:
+ /**
+ * @brief 数据库连接状态变化信号
+ * @param available 是否可用
+ */
+ void databaseAvailabilityChanged(bool available);
+
+ /**
+ * @brief 连接池状态变化信号
+ * @param activeConnections 活跃连接数
+ * @param totalConnections 总连接数
+ */
+ void poolStatusChanged(int activeConnections, int totalConnections);
+
+private:
+ /**
+ * @brief 私有构造函数
+ */
+ explicit DatabaseManager(QObject* parent = nullptr);
+
+ /**
+ * @brief 创建新的数据库连接
+ * @param connectionName 连接名称
+ * @return QSqlDatabase 数据库对象
+ */
+ QSqlDatabase createConnection(const QString& connectionName);
+
+ /**
+ * @brief 生成连接名称
+ * @return QString 唯一连接名
+ */
+ QString generateConnectionName();
+
+ /**
+ * @brief 启动健康检查定时器
+ */
+ void startHealthCheckTimer();
+
+private:
+ static std::unique_ptr m_instance; ///< 单例实例
+ static std::mutex m_instanceMutex; ///< 实例互斥锁
+
+ mutable std::mutex m_mutex; ///< 访问互斥锁
+ std::vector m_availableConnections; ///< 可用连接池
+ std::vector m_activeConnections; ///< 活跃连接池
+
+ int m_maxConnections; ///< 最大连接数
+ int m_connectionCounter; ///< 连接计数器
+ bool m_initialized; ///< 初始化状态
+ bool m_databaseAvailable; ///< 数据库可用状态
+
+ std::unique_ptr m_healthCheckTimer; ///< 健康检查定时器
+ ConfigManager* m_configManager; ///< 配置管理器
+
+ // 统计信息
+ mutable std::mutex m_statsMutex; ///< 统计信息互斥锁
+ int m_totalConnectionsCreated; ///< 总创建连接数
+ int m_totalQueriesExecuted; ///< 总执行查询数
+ int m_failedConnections; ///< 失败连接数
+};
+
+/**
+ * @class DatabaseTransaction
+ * @brief RAII风格的数据库事务管理器
+ *
+ * 自动管理数据库事务,确保异常安全性。
+ *
+ * @since 2.0
+ */
+class DatabaseTransaction
+{
+public:
+ /**
+ * @brief 构造函数 - 自动开始事务
+ * @param connection 数据库连接
+ */
+ explicit DatabaseTransaction(DatabaseConnection& connection);
+
+ /**
+ * @brief 析构函数 - 自动回滚未提交的事务
+ */
+ ~DatabaseTransaction();
+
+ // 禁用拷贝和移动
+ DatabaseTransaction(const DatabaseTransaction&) = delete;
+ DatabaseTransaction& operator=(const DatabaseTransaction&) = delete;
+ DatabaseTransaction(DatabaseTransaction&&) = delete;
+ DatabaseTransaction& operator=(DatabaseTransaction&&) = delete;
+
+ /**
+ * @brief 提交事务
+ * @return bool 是否成功
+ */
+ bool commit();
+
+ /**
+ * @brief 回滚事务
+ * @return bool 是否成功
+ */
+ bool rollback();
+
+ /**
+ * @brief 检查事务是否活跃
+ * @return bool 事务状态
+ */
+ bool isActive() const;
+
+private:
+ DatabaseConnection& m_connection; ///< 数据库连接引用
+ bool m_committed; ///< 是否已提交
+ bool m_active; ///< 事务是否活跃
+};
+
+#endif // DATABASEMANAGER_H
\ No newline at end of file
diff --git a/src/Client/include/ui/components/DeviceListPanel.h b/src/Client/include/ui/components/DeviceListPanel.h
index e7b85300..8e872e61 100644
--- a/src/Client/include/ui/components/DeviceListPanel.h
+++ b/src/Client/include/ui/components/DeviceListPanel.h
@@ -364,7 +364,7 @@ private:
// 布局管理器
QVBoxLayout *m_mainLayout; ///< 主布局
QHBoxLayout *m_headerLayout; ///< 头部布局
- QHBoxLayout *m_buttonLayout; ///< 按钮区域布局
+ QVBoxLayout *m_buttonLayout; ///< 按钮区域布局(现在是垂直布局)
// 数据管理
QHash m_deviceCards; ///< 设备卡片映射表
diff --git a/src/Client/include/ui/components/RightFunctionPanel.h b/src/Client/include/ui/components/RightFunctionPanel.h
index 884f24b9..84e1517c 100644
--- a/src/Client/include/ui/components/RightFunctionPanel.h
+++ b/src/Client/include/ui/components/RightFunctionPanel.h
@@ -137,41 +137,51 @@ public:
signals:
// 战场探索模块信号
+ /**
+ * @brief 无人机控制界面请求信号
+ */
+ void droneControlRequested();
+
+ /**
+ * @brief 机器狗控制界面请求信号
+ */
+ void robotDogControlRequested();
+
/**
* @brief 开始自主建图信号
*/
void startMapping();
-
+
/**
* @brief 停止自主建图信号
*/
void stopMapping();
-
+
/**
* @brief 开始导航避障信号
*/
void startNavigation();
-
+
/**
* @brief 停止导航避障信号
*/
void stopNavigation();
-
+
/**
* @brief 开始照片传输信号
*/
void startPhotoTransmission();
-
+
/**
* @brief 停止照片传输信号
*/
void stopPhotoTransmission();
-
+
/**
* @brief 开始人物识别信号
*/
void startPersonRecognition();
-
+
/**
* @brief 停止人物识别信号
*/
@@ -183,6 +193,11 @@ signals:
*/
void openIntelligenceUI();
+ /**
+ * @brief 打开面部灯光控制界面信号
+ */
+ void openFaceLightUI();
+
// 敌情统计模块信号
/**
* @brief 刷新敌情统计信号
@@ -216,27 +231,37 @@ public slots:
void updateDeviceStatus(const QString &deviceName, bool online, int battery);
private slots:
+ /**
+ * @brief 无人机控制按钮点击槽函数
+ */
+ void onDroneControlClicked();
+
+ /**
+ * @brief 机器狗控制按钮点击槽函数
+ */
+ void onRobotDogControlClicked();
+
/**
* @brief 设备选择槽函数
* @param deviceName 设备名称
*/
void onDeviceSelected(const QString &deviceName);
-
+
/**
* @brief 自主建图开关槽函数
*/
void onMappingToggle();
-
+
/**
* @brief 导航避障开关槽函数
*/
void onNavigationToggle();
-
+
/**
* @brief 照片传输开关槽函数
*/
void onPhotoTransmissionToggle();
-
+
/**
* @brief 人物识别开关槽函数
*/
@@ -247,6 +272,11 @@ private slots:
*/
void onOpenIntelligenceUI();
+ /**
+ * @brief 打开面部灯光控制界面槽函数
+ */
+ void onOpenFaceLightUI();
+
/**
* @brief 刷新统计槽函数
*/
@@ -288,8 +318,10 @@ private:
// 战场探索模块
ModuleCard *m_explorationCard; ///< 探索模块卡片
- RightDeviceCard *m_robotDogCard; ///< 机器狗设备卡片
- RightDeviceCard *m_droneCard; ///< 无人机设备卡片
+ QPushButton *m_droneControlBtn; ///< 无人机控制按钮
+ QPushButton *m_robotDogControlBtn; ///< 机器狗控制按钮
+ // RightDeviceCard *m_robotDogCard; ///< 机器狗设备卡片(已删除,不再使用)
+ // RightDeviceCard *m_droneCard; ///< 无人机设备卡片(已删除,不再使用)
QPushButton *m_mappingBtn; ///< 建图按钮
QPushButton *m_navigationBtn; ///< 导航按钮
QPushButton *m_photoBtn; ///< 照片传输按钮
@@ -299,6 +331,7 @@ private:
// 情报传输模块
ModuleCard *m_intelligenceCard; ///< 情报模块卡片
QPushButton *m_voiceCallBtn; ///< 音频控制按钮
+ QPushButton *m_faceLightBtn; ///< 面部灯光控制按钮
// 敌情统计模块
ModuleCard *m_statsCard; ///< 统计模块卡片
diff --git a/src/Client/include/ui/dialogs/DroneControlDialog.h b/src/Client/include/ui/dialogs/DroneControlDialog.h
new file mode 100644
index 00000000..b2036900
--- /dev/null
+++ b/src/Client/include/ui/dialogs/DroneControlDialog.h
@@ -0,0 +1,232 @@
+/**
+ * @file DroneControlDialog.h
+ * @brief 无人机控制对话框定义
+ * @author Qt UI Optimizer
+ * @date 2024-07-04
+ * @version 1.0
+ *
+ * 无人机专用控制界面,包含:
+ * - 飞行控制(起飞、降落、悬停)
+ * - 航线规划和导航
+ * - 实时视频传输
+ * - 照片拍摄和传输
+ * - 人物识别功能
+ * - 设备状态监控
+ *
+ * @note 依赖Qt GUI模块和ModernStyleManager
+ * @since 1.0
+ */
+
+#ifndef DRONECONTROLDIALOG_H
+#define DRONECONTROLDIALOG_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/**
+ * @class DroneControlDialog
+ * @brief 无人机控制对话框
+ *
+ * 提供完整的无人机控制功能界面,采用模块化设计
+ */
+class DroneControlDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ /**
+ * @brief 构造函数
+ * @param parent 父窗口指针
+ */
+ explicit DroneControlDialog(QWidget *parent = nullptr);
+
+ /**
+ * @brief 析构函数
+ */
+ ~DroneControlDialog();
+
+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();
+
+public slots:
+ /**
+ * @brief 更新无人机状态
+ * @param battery 电池电量
+ * @param altitude 飞行高度
+ * @param speed 飞行速度
+ */
+ void updateDroneStatus(int battery, double altitude, double speed);
+
+private slots:
+ /**
+ * @brief 起飞按钮点击槽函数
+ */
+ void onTakeoffClicked();
+
+ /**
+ * @brief 降落按钮点击槽函数
+ */
+ void onLandClicked();
+
+ /**
+ * @brief 悬停按钮点击槽函数
+ */
+ void onHoverClicked();
+
+ /**
+ * @brief 返航按钮点击槽函数
+ */
+ void onReturnHomeClicked();
+
+ /**
+ * @brief 建图开关槽函数
+ */
+ void onMappingToggle();
+
+ /**
+ * @brief 导航开关槽函数
+ */
+ void onNavigationToggle();
+
+ /**
+ * @brief 照片传输开关槽函数
+ */
+ void onPhotoTransmissionToggle();
+
+ /**
+ * @brief 人物识别开关槽函数
+ */
+ void onPersonRecognitionToggle();
+
+ /**
+ * @brief 紧急停止槽函数
+ */
+ void onEmergencyStop();
+
+private:
+ /**
+ * @brief 设置UI界面
+ */
+ void setupUI();
+
+ /**
+ * @brief 设置飞行控制模块
+ */
+ void setupFlightControlModule();
+
+ /**
+ * @brief 设置任务控制模块
+ */
+ void setupMissionControlModule();
+
+ /**
+ * @brief 设置状态监控模块
+ */
+ void setupStatusMonitorModule();
+
+ /**
+ * @brief 应用样式表
+ */
+ void applyStyles();
+
+ /**
+ * @brief 连接信号槽
+ */
+ void connectSignals();
+
+private:
+ // 主布局
+ QVBoxLayout *m_mainLayout;
+ QHBoxLayout *m_contentLayout;
+
+ // 飞行控制模块
+ QGroupBox *m_flightControlGroup;
+ QPushButton *m_takeoffBtn;
+ QPushButton *m_landBtn;
+ QPushButton *m_hoverBtn;
+ QPushButton *m_returnHomeBtn;
+ QPushButton *m_emergencyStopBtn;
+ QSlider *m_altitudeSlider;
+ QSlider *m_speedSlider;
+
+ // 任务控制模块
+ QGroupBox *m_missionControlGroup;
+ QPushButton *m_mappingBtn;
+ QPushButton *m_navigationBtn;
+ QPushButton *m_photoBtn;
+ QPushButton *m_recognitionBtn;
+ QComboBox *m_missionModeCombo;
+
+ // 状态监控模块
+ QGroupBox *m_statusGroup;
+ QLabel *m_batteryLabel;
+ QProgressBar *m_batteryProgress;
+ QLabel *m_altitudeLabel;
+ QLabel *m_speedLabel;
+ QLabel *m_gpsLabel;
+ QLabel *m_connectionLabel;
+ QTextEdit *m_logTextEdit;
+
+ // 状态变量
+ bool m_isMappingActive;
+ bool m_isNavigationActive;
+ bool m_isPhotoTransmissionActive;
+ bool m_isPersonRecognitionActive;
+ bool m_isFlying;
+
+ // 定时器
+ QTimer *m_statusUpdateTimer;
+};
+
+#endif // DRONECONTROLDIALOG_H
diff --git a/src/Client/include/ui/dialogs/RobotDogControlDialog.h b/src/Client/include/ui/dialogs/RobotDogControlDialog.h
new file mode 100644
index 00000000..025ab1ed
--- /dev/null
+++ b/src/Client/include/ui/dialogs/RobotDogControlDialog.h
@@ -0,0 +1,255 @@
+/**
+ * @file RobotDogControlDialog.h
+ * @brief 机器狗控制对话框定义
+ * @author Qt UI Optimizer
+ * @date 2024-07-04
+ * @version 1.0
+ *
+ * 机器狗专用控制界面,包含:
+ * - 运动控制(前进、后退、转向、停止)
+ * - 姿态控制(站立、趴下、跳跃)
+ * - 地图建构和导航
+ * - 视觉识别和跟踪
+ * - 设备状态监控
+ *
+ * @note 依赖Qt GUI模块和ModernStyleManager
+ * @since 1.0
+ */
+
+#ifndef ROBOTDOGCONTROLDIALOG_H
+#define ROBOTDOGCONTROLDIALOG_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/**
+ * @class RobotDogControlDialog
+ * @brief 机器狗控制对话框
+ *
+ * 提供完整的机器狗控制功能界面,采用模块化设计
+ */
+class RobotDogControlDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ /**
+ * @brief 构造函数
+ * @param parent 父窗口指针
+ */
+ explicit RobotDogControlDialog(QWidget *parent = nullptr);
+
+ /**
+ * @brief 析构函数
+ */
+ ~RobotDogControlDialog();
+
+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();
+
+public slots:
+ /**
+ * @brief 更新机器狗状态
+ * @param battery 电池电量
+ * @param speed 移动速度
+ * @param temperature 温度
+ */
+ void updateRobotStatus(int battery, double speed, double temperature);
+
+private slots:
+ /**
+ * @brief 前进按钮点击槽函数
+ */
+ void onMoveForwardClicked();
+
+ /**
+ * @brief 后退按钮点击槽函数
+ */
+ void onMoveBackwardClicked();
+
+ /**
+ * @brief 左转按钮点击槽函数
+ */
+ void onTurnLeftClicked();
+
+ /**
+ * @brief 右转按钮点击槽函数
+ */
+ void onTurnRightClicked();
+
+ /**
+ * @brief 停止按钮点击槽函数
+ */
+ void onStopClicked();
+
+ /**
+ * @brief 站立按钮点击槽函数
+ */
+ void onStandClicked();
+
+ /**
+ * @brief 趴下按钮点击槽函数
+ */
+ void onLieDownClicked();
+
+ /**
+ * @brief 跳跃按钮点击槽函数
+ */
+ void onJumpClicked();
+
+ /**
+ * @brief 建图开关槽函数
+ */
+ void onMappingToggle();
+
+ /**
+ * @brief 导航开关槽函数
+ */
+ void onNavigationToggle();
+
+ /**
+ * @brief 照片传输开关槽函数
+ */
+ void onPhotoTransmissionToggle();
+
+ /**
+ * @brief 人物识别开关槽函数
+ */
+ void onPersonRecognitionToggle();
+
+ /**
+ * @brief 紧急停止槽函数
+ */
+ void onEmergencyStop();
+
+private:
+ /**
+ * @brief 设置UI界面
+ */
+ void setupUI();
+
+ /**
+ * @brief 设置运动控制模块
+ */
+ void setupMovementControlModule();
+
+ /**
+ * @brief 设置任务控制模块
+ */
+ void setupMissionControlModule();
+
+ /**
+ * @brief 设置状态监控模块
+ */
+ void setupStatusMonitorModule();
+
+ /**
+ * @brief 应用样式表
+ */
+ void applyStyles();
+
+ /**
+ * @brief 连接信号槽
+ */
+ void connectSignals();
+
+private:
+ // 主布局
+ QVBoxLayout *m_mainLayout;
+ QHBoxLayout *m_contentLayout;
+
+ // 运动控制模块
+ QGroupBox *m_movementControlGroup;
+ QPushButton *m_forwardBtn;
+ QPushButton *m_backwardBtn;
+ QPushButton *m_leftBtn;
+ QPushButton *m_rightBtn;
+ QPushButton *m_stopBtn;
+ QPushButton *m_standBtn;
+ QPushButton *m_lieDownBtn;
+ QPushButton *m_jumpBtn;
+ QPushButton *m_emergencyStopBtn;
+ QSlider *m_speedSlider;
+
+ // 任务控制模块
+ QGroupBox *m_missionControlGroup;
+ QPushButton *m_mappingBtn;
+ QPushButton *m_navigationBtn;
+ QPushButton *m_photoBtn;
+ QPushButton *m_recognitionBtn;
+ QComboBox *m_missionModeCombo;
+
+ // 状态监控模块
+ QGroupBox *m_statusGroup;
+ QLabel *m_batteryLabel;
+ QProgressBar *m_batteryProgress;
+ QLabel *m_speedLabel;
+ QLabel *m_temperatureLabel;
+ QLabel *m_postureLabel;
+ QLabel *m_connectionLabel;
+ QTextEdit *m_logTextEdit;
+
+ // 状态变量
+ bool m_isMappingActive;
+ bool m_isNavigationActive;
+ bool m_isPhotoTransmissionActive;
+ bool m_isPersonRecognitionActive;
+ bool m_isMoving;
+ QString m_currentPosture;
+
+ // 定时器
+ QTimer *m_statusUpdateTimer;
+};
+
+#endif // ROBOTDOGCONTROLDIALOG_H
diff --git a/src/Client/include/ui/main/MainWindow.h b/src/Client/include/ui/main/MainWindow.h
index 05969b0f..23e41920 100644
--- a/src/Client/include/ui/main/MainWindow.h
+++ b/src/Client/include/ui/main/MainWindow.h
@@ -40,9 +40,12 @@
// 自定义模块头文件
#include "AudioModule/IntelligenceUI.h"
+#include "FaceLightModule/FaceLightControl.h"
#include "ui/components/DeviceListPanel.h"
#include "ui/components/SystemLogPanel.h"
#include "ui/components/RightFunctionPanel.h"
+// #include "ui/dialogs/DroneControlDialog.h"
+// #include "ui/dialogs/RobotDogControlDialog.h"
// 标准库头文件
#include
@@ -192,6 +195,11 @@ private slots:
*/
void onIntelligenceClicked();
+ /**
+ * @brief FaceLight控制按钮点击槽函数
+ */
+ void onFaceLightClicked();
+
/**
* @brief 设备选中槽函数
* @param deviceId 设备ID
@@ -223,42 +231,53 @@ private slots:
void onAddDeviceRequested(const QString &deviceType);
private slots:
+ // 战场探索模块控制槽函数
+ /**
+ * @brief 无人机控制请求槽函数
+ */
+ void onDroneControlRequested();
+
+ /**
+ * @brief 机器狗控制请求槽函数
+ */
+ void onRobotDogControlRequested();
+
// 右侧功能面板信号处理槽函数
/**
* @brief 开始自主建图槽函数
*/
void onStartMapping();
-
+
/**
* @brief 停止自主建图槽函数
*/
void onStopMapping();
-
+
/**
* @brief 开始导航避障槽函数
*/
void onStartNavigation();
-
+
/**
* @brief 停止导航避障槽函数
*/
void onStopNavigation();
-
+
/**
* @brief 开始照片传输槽函数
*/
void onStartPhotoTransmission();
-
+
/**
* @brief 停止照片传输槽函数
*/
void onStopPhotoTransmission();
-
+
/**
* @brief 开始人物识别槽函数
*/
void onStartPersonRecognition();
-
+
/**
* @brief 停止人物识别槽函数
*/
@@ -313,19 +332,14 @@ private:
void setupStyle();
/**
- * @brief 设置菜单栏样式
- */
- void setupMenuBarStyle();
-
- /**
- * @brief 设置状态栏样式
+ * @brief 初始化地图上的设备标记
*/
- void setupStatusBarStyle();
+ void initializeDeviceMarkersOnMap();
/**
- * @brief 初始化地图上的设备标记
+ * @brief 修复主要功能按钮布局
*/
- void initializeDeviceMarkersOnMap();
+ void fixMainButtonLayout();
/**
* @brief 初始化现代样式管理器
@@ -335,12 +349,18 @@ private:
private:
Ui::MainWindow *m_ui; ///< UI界面指针
IntelligenceUI *m_intelligenceUI; ///< 情报传达界面指针
+ FaceLightControl *m_faceLightControl; ///< 面部灯光控制界面指针
DeviceListPanel *m_deviceListPanel; ///< 设备列表面板组件
SystemLogPanel *m_systemLogPanel; ///< 系统日志面板组件
RightFunctionPanel *m_rightFunctionPanel; ///< 右侧功能面板组件
QSplitter *m_leftPanelSplitter; ///< 左侧面板分割器
QVector> m_robotList; ///< 机器人列表(名称-IP地址对)
QVector> m_uavList; ///< 无人机列表(名称-IP地址对)
+
+ // 控制对话框(暂时注释掉以避免编译问题)
+ // DroneControlDialog *m_droneControlDialog; ///< 无人机控制对话框
+ // RobotDogControlDialog *m_robotDogControlDialog; ///< 机器狗控制对话框
+
// 人脸识别相关成员变量已移除(功能暂未实现)
};
#endif // MAINWINDOW_H
diff --git a/src/Client/src/core/database/DatabaseConfig.cpp b/src/Client/src/core/database/DatabaseConfig.cpp
new file mode 100644
index 00000000..999cdfa3
--- /dev/null
+++ b/src/Client/src/core/database/DatabaseConfig.cpp
@@ -0,0 +1,198 @@
+/**
+ * @file DatabaseConfig.cpp
+ * @brief 数据库配置类实现
+ * @author BattlefieldExplorationSystem Team
+ * @date 2024-01-01
+ * @version 2.0
+ */
+
+#include "core/database/DatabaseConfig.h"
+#include
+#include
+#include
+#include
+
+// 静态成员初始化
+DatabaseConfig* DatabaseConfig::m_instance = nullptr;
+
+DatabaseConfig* DatabaseConfig::getInstance()
+{
+ if (m_instance == nullptr) {
+ m_instance = new DatabaseConfig();
+ }
+ return m_instance;
+}
+
+DatabaseConfig::DatabaseConfig()
+ : m_host("localhost")
+ , m_port(3306)
+ , m_databaseName("Client")
+ , m_username("root")
+ , m_password("hzk200407140238")
+ , m_connectTimeout(30)
+ , m_maxConnections(10)
+ , m_settings(nullptr)
+{
+ initDefaultConfig();
+ loadConfig();
+}
+
+DatabaseConfig::~DatabaseConfig()
+{
+ if (m_settings) {
+ delete m_settings;
+ m_settings = nullptr;
+ }
+}
+
+void DatabaseConfig::initDefaultConfig()
+{
+ // 初始化默认数据库配置
+ m_host = "localhost";
+ m_port = 3306;
+ m_databaseName = "Client";
+ m_username = "root";
+ m_password = "hzk200407140238";
+ m_connectTimeout = 30;
+ m_maxConnections = 10;
+}
+
+QString DatabaseConfig::getHost() const
+{
+ return m_host;
+}
+
+int DatabaseConfig::getPort() const
+{
+ return m_port;
+}
+
+QString DatabaseConfig::getDatabaseName() const
+{
+ return m_databaseName;
+}
+
+QString DatabaseConfig::getUsername() const
+{
+ return m_username;
+}
+
+QString DatabaseConfig::getPassword() const
+{
+ return m_password;
+}
+
+int DatabaseConfig::getConnectTimeout() const
+{
+ return m_connectTimeout;
+}
+
+int DatabaseConfig::getMaxConnections() const
+{
+ return m_maxConnections;
+}
+
+void DatabaseConfig::setDatabaseConfig(const QString& host, int port, const QString& dbName,
+ const QString& username, const QString& password)
+{
+ m_host = host;
+ m_port = port;
+ m_databaseName = dbName;
+ m_username = username;
+ m_password = password;
+}
+
+bool DatabaseConfig::loadConfig(const QString& configPath)
+{
+ QString configFile = configPath;
+ if (configFile.isEmpty()) {
+ // 使用默认配置文件路径
+ configFile = QCoreApplication::applicationDirPath() + "/config/database.ini";
+
+ // 如果应用程序目录没有配置文件,尝试用户配置目录
+ if (!QDir(configFile).exists()) {
+ QString userConfigDir = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
+ configFile = userConfigDir + "/BattlefieldExplorationSystem/database.ini";
+ }
+ }
+
+ if (m_settings) {
+ delete m_settings;
+ }
+
+ m_settings = new QSettings(configFile, QSettings::IniFormat);
+
+ if (!QDir(configFile).exists()) {
+ qDebug() << "Database config file not found, using defaults:" << configFile;
+ return false;
+ }
+
+ // 读取数据库配置
+ m_settings->beginGroup("Database");
+ m_host = m_settings->value("host", m_host).toString();
+ m_port = m_settings->value("port", m_port).toInt();
+ m_databaseName = m_settings->value("databaseName", m_databaseName).toString();
+ m_username = m_settings->value("username", m_username).toString();
+ m_password = m_settings->value("password", m_password).toString();
+ m_settings->endGroup();
+
+ // 读取连接池配置
+ m_settings->beginGroup("ConnectionPool");
+ m_connectTimeout = m_settings->value("connectTimeout", m_connectTimeout).toInt();
+ m_maxConnections = m_settings->value("maxConnections", m_maxConnections).toInt();
+ m_settings->endGroup();
+
+ qDebug() << "Database config loaded from:" << configFile;
+ return true;
+}
+
+bool DatabaseConfig::saveConfig(const QString& configPath)
+{
+ QString configFile = configPath;
+ if (configFile.isEmpty()) {
+ configFile = QCoreApplication::applicationDirPath() + "/config/database.ini";
+ }
+
+ // 确保配置目录存在
+ QDir configDir = QFileInfo(configFile).absoluteDir();
+ if (!configDir.exists()) {
+ configDir.mkpath(".");
+ }
+
+ if (m_settings) {
+ delete m_settings;
+ }
+
+ m_settings = new QSettings(configFile, QSettings::IniFormat);
+
+ // 保存数据库配置
+ m_settings->beginGroup("Database");
+ m_settings->setValue("host", m_host);
+ m_settings->setValue("port", m_port);
+ m_settings->setValue("databaseName", m_databaseName);
+ m_settings->setValue("username", m_username);
+ m_settings->setValue("password", m_password);
+ m_settings->endGroup();
+
+ // 保存连接池配置
+ m_settings->beginGroup("ConnectionPool");
+ m_settings->setValue("connectTimeout", m_connectTimeout);
+ m_settings->setValue("maxConnections", m_maxConnections);
+ m_settings->endGroup();
+
+ m_settings->sync();
+
+ qDebug() << "Database config saved to:" << configFile;
+ return true;
+}
+
+DatabaseConnectionInfo DatabaseConfig::getConnectionInfo() const
+{
+ DatabaseConnectionInfo info;
+ info.hostName = m_host;
+ info.port = m_port;
+ info.databaseName = m_databaseName;
+ info.username = m_username;
+ info.password = m_password;
+ return info;
+}
\ No newline at end of file
diff --git a/src/Client/src/core/database/DatabaseHelper.cpp b/src/Client/src/core/database/DatabaseHelper.cpp
new file mode 100644
index 00000000..3de2a89f
--- /dev/null
+++ b/src/Client/src/core/database/DatabaseHelper.cpp
@@ -0,0 +1,348 @@
+/**
+ * @file DatabaseHelper.cpp
+ * @brief 数据库助手类实现
+ * @author BattlefieldExplorationSystem Team
+ * @date 2024-01-01
+ * @version 2.0
+ */
+
+#include "core/database/DatabaseHelper.h"
+#include "core/database/DatabaseConfig.h"
+#include
+#include
+#include
+#include
+#include
+
+// 静态成员初始化
+DatabaseHelper* DatabaseHelper::m_instance = nullptr;
+QMutex DatabaseHelper::m_mutex;
+QMap DatabaseHelper::m_connections;
+int DatabaseHelper::m_connectionCounter = 0;
+
+DatabaseHelper* DatabaseHelper::getInstance()
+{
+ QMutexLocker locker(&m_mutex);
+ if (m_instance == nullptr) {
+ m_instance = new DatabaseHelper();
+ }
+ return m_instance;
+}
+
+DatabaseHelper::DatabaseHelper()
+{
+ // 初始化数据库助手
+}
+
+DatabaseHelper::~DatabaseHelper()
+{
+ closeAllConnections();
+}
+
+QString DatabaseHelper::generateConnectionName()
+{
+ QMutexLocker locker(&m_mutex);
+ return QString("Connection_%1_%2").arg(++m_connectionCounter).arg(reinterpret_cast(QThread::currentThreadId()));
+}
+
+QSqlDatabase DatabaseHelper::createConnection(const QString& connectionName)
+{
+ QString connName = connectionName;
+ if (connName.isEmpty()) {
+ connName = generateConnectionName();
+ }
+
+ QMutexLocker locker(&m_mutex);
+
+ // 如果连接已存在且有效,直接返回
+ if (m_connections.contains(connName)) {
+ QSqlDatabase existingDb = m_connections[connName];
+ if (existingDb.isValid() && existingDb.isOpen()) {
+ return existingDb;
+ } else {
+ // 移除无效连接
+ m_connections.remove(connName);
+ QSqlDatabase::removeDatabase(connName);
+ }
+ }
+
+ // 创建新连接
+ QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", connName);
+
+ if (!configureConnection(db)) {
+ qWarning() << "Failed to configure database connection:" << connName;
+ QSqlDatabase::removeDatabase(connName);
+ return QSqlDatabase();
+ }
+
+ if (!db.open()) {
+ qWarning() << "Failed to open database connection:" << connName << db.lastError().text();
+ QSqlDatabase::removeDatabase(connName);
+ return QSqlDatabase();
+ }
+
+ m_connections[connName] = db;
+ qDebug() << "Database connection created:" << connName;
+ return db;
+}
+
+QSqlDatabase DatabaseHelper::createTempConnection(const QString& connectionName)
+{
+ QString tempConnName = connectionName + "_" + QUuid::createUuid().toString(QUuid::WithoutBraces);
+ return createConnection(tempConnName);
+}
+
+bool DatabaseHelper::configureConnection(QSqlDatabase& db)
+{
+ DatabaseConfig* config = DatabaseConfig::getInstance();
+
+ db.setHostName(config->getHost());
+ db.setPort(config->getPort());
+ db.setDatabaseName(config->getDatabaseName());
+ db.setUserName(config->getUsername());
+ db.setPassword(config->getPassword());
+
+ // 设置连接选项
+ db.setConnectOptions("MYSQL_OPT_CONNECT_TIMEOUT=" + QString::number(config->getConnectTimeout()) +
+ ";MYSQL_OPT_RECONNECT=1");
+
+ return true;
+}
+
+void DatabaseHelper::closeConnection(const QString& connectionName)
+{
+ QMutexLocker locker(&m_mutex);
+
+ if (m_connections.contains(connectionName)) {
+ QSqlDatabase db = m_connections[connectionName];
+ if (db.isOpen()) {
+ db.close();
+ }
+ m_connections.remove(connectionName);
+ QSqlDatabase::removeDatabase(connectionName);
+ qDebug() << "Database connection closed:" << connectionName;
+ }
+}
+
+void DatabaseHelper::closeAllConnections()
+{
+ QMutexLocker locker(&m_mutex);
+
+ QStringList connectionNames = m_connections.keys();
+ for (const QString& name : connectionNames) {
+ QSqlDatabase db = m_connections[name];
+ if (db.isOpen()) {
+ db.close();
+ }
+ QSqlDatabase::removeDatabase(name);
+ }
+ m_connections.clear();
+ qDebug() << "All database connections closed";
+}
+
+bool DatabaseHelper::isConnectionValid(const QString& connectionName)
+{
+ QMutexLocker locker(&m_mutex);
+
+ if (!m_connections.contains(connectionName)) {
+ return false;
+ }
+
+ QSqlDatabase db = m_connections[connectionName];
+ return db.isValid() && db.isOpen();
+}
+
+QSqlQuery DatabaseHelper::executeQuery(const QString& query, const QString& connectionName)
+{
+ QString connName = connectionName;
+ if (connName.isEmpty()) {
+ connName = generateConnectionName();
+ }
+
+ QSqlDatabase db = createConnection(connName);
+ if (!db.isValid()) {
+ qWarning() << "Invalid database connection for query execution";
+ return QSqlQuery();
+ }
+
+ QSqlQuery sqlQuery(db);
+ if (!sqlQuery.exec(query)) {
+ qWarning() << "Query execution failed:" << query << sqlQuery.lastError().text();
+ }
+
+ return sqlQuery;
+}
+
+bool DatabaseHelper::beginTransaction(const QString& connectionName)
+{
+ if (!isConnectionValid(connectionName)) {
+ return false;
+ }
+
+ QSqlDatabase db = m_connections[connectionName];
+ return db.transaction();
+}
+
+bool DatabaseHelper::commitTransaction(const QString& connectionName)
+{
+ if (!isConnectionValid(connectionName)) {
+ return false;
+ }
+
+ QSqlDatabase db = m_connections[connectionName];
+ return db.commit();
+}
+
+bool DatabaseHelper::rollbackTransaction(const QString& connectionName)
+{
+ if (!isConnectionValid(connectionName)) {
+ return false;
+ }
+
+ QSqlDatabase db = m_connections[connectionName];
+ return db.rollback();
+}
+
+QString DatabaseHelper::getLastError(const QString& connectionName)
+{
+ if (!isConnectionValid(connectionName)) {
+ return "Invalid connection";
+ }
+
+ QSqlDatabase db = m_connections[connectionName];
+ return db.lastError().text();
+}
+
+bool DatabaseHelper::testConnection()
+{
+ QSqlDatabase testDb = createConnection("TestConnection");
+ bool success = testDb.isValid() && testDb.isOpen();
+ closeConnection("TestConnection");
+ return success;
+}
+
+bool DatabaseHelper::initializeDatabase()
+{
+ qDebug() << "Initializing database...";
+
+ if (!testConnection()) {
+ qWarning() << "Database connection test failed";
+ return false;
+ }
+
+ return createTables();
+}
+
+bool DatabaseHelper::createTables()
+{
+ QSqlDatabase db = createConnection("InitConnection");
+ if (!db.isValid()) {
+ qWarning() << "Failed to create database connection for table creation";
+ return false;
+ }
+
+ bool success = true;
+ success &= createDevicesTable(db);
+ success &= createOperationLogsTable(db);
+ success &= createSystemConfigTable(db);
+
+ closeConnection("InitConnection");
+
+ if (success) {
+ qDebug() << "Database tables created successfully";
+ } else {
+ qWarning() << "Failed to create some database tables";
+ }
+
+ return success;
+}
+
+bool DatabaseHelper::createDevicesTable(QSqlDatabase& db)
+{
+ QSqlQuery query(db);
+ QString sql = R"(
+ CREATE TABLE IF NOT EXISTS devices (
+ id VARCHAR(50) PRIMARY KEY,
+ name VARCHAR(100) NOT NULL,
+ device_type ENUM('uav', 'dog') NOT NULL,
+ ip VARCHAR(15) NOT NULL,
+ port INT NOT NULL,
+ state INT NOT NULL DEFAULT 0,
+ longitude DOUBLE DEFAULT 0.0,
+ latitude DOUBLE DEFAULT 0.0,
+ signal_strength INT DEFAULT 0,
+ battery_level INT DEFAULT 100,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ INDEX idx_device_type (device_type),
+ INDEX idx_state (state)
+ )
+ )";
+
+ if (!query.exec(sql)) {
+ qWarning() << "Failed to create devices table:" << query.lastError().text();
+ return false;
+ }
+
+ return true;
+}
+
+bool DatabaseHelper::createOperationLogsTable(QSqlDatabase& db)
+{
+ QSqlQuery query(db);
+ QString sql = R"(
+ CREATE TABLE IF NOT EXISTS device_operation_logs (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ device_id VARCHAR(50) NOT NULL,
+ device_type ENUM('uav', 'dog') NOT NULL,
+ operation VARCHAR(100) NOT NULL,
+ operation_result VARCHAR(20) NOT NULL,
+ operator VARCHAR(50) NOT NULL,
+ operation_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ INDEX idx_device_id (device_id),
+ INDEX idx_operation_time (operation_time)
+ )
+ )";
+
+ if (!query.exec(sql)) {
+ qWarning() << "Failed to create operation logs table:" << query.lastError().text();
+ return false;
+ }
+
+ return true;
+}
+
+bool DatabaseHelper::createSystemConfigTable(QSqlDatabase& db)
+{
+ QSqlQuery query(db);
+ QString sql = R"(
+ CREATE TABLE IF NOT EXISTS system_config (
+ config_key VARCHAR(100) PRIMARY KEY,
+ config_value TEXT,
+ description VARCHAR(255),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+ )
+ )";
+
+ if (!query.exec(sql)) {
+ qWarning() << "Failed to create system config table:" << query.lastError().text();
+ return false;
+ }
+
+ // 插入默认配置
+ QString insertDefaults = R"(
+ INSERT IGNORE INTO system_config (config_key, config_value, description) VALUES
+ ('map.default_center_lon', '116.4', '默认地图中心经度'),
+ ('map.default_center_lat', '39.9', '默认地图中心纬度'),
+ ('system.version', '2.0.0', '系统版本'),
+ ('system.name', 'BattlefieldExplorationSystem', '系统名称')
+ )";
+
+ if (!query.exec(insertDefaults)) {
+ qWarning() << "Failed to insert default config:" << query.lastError().text();
+ return false;
+ }
+
+ return true;
+}
\ No newline at end of file
diff --git a/src/Client/src/core/database/DatabaseManager.cpp b/src/Client/src/core/database/DatabaseManager.cpp
new file mode 100644
index 00000000..714f310d
--- /dev/null
+++ b/src/Client/src/core/database/DatabaseManager.cpp
@@ -0,0 +1,475 @@
+/**
+ * @file DatabaseManager.cpp
+ * @brief 数据库连接管理器实现
+ * @author BattlefieldExplorationSystem Team
+ * @date 2025-06-30
+ * @version 2.0
+ */
+
+#include "core/database/DatabaseManager.h"
+#include "utils/ConfigManager.h"
+
+// C++标准库头文件
+#include
+#include
+
+// Qt头文件
+#include
+#include
+#include
+#include
+#include
+#include
+
+// DatabaseConnection 实现
+
+DatabaseConnection::DatabaseConnection(const QString& connectionName, bool autoReconnect)
+ : m_connectionName(connectionName)
+ , m_autoReconnect(autoReconnect)
+ , m_isValid(false)
+{
+ if (QSqlDatabase::contains(m_connectionName)) {
+ m_database = QSqlDatabase::database(m_connectionName);
+ } else {
+ // 创建新连接
+ ConfigManager& config = ConfigManager::getInstance();
+
+ m_database = QSqlDatabase::addDatabase("QMYSQL", m_connectionName);
+ m_database.setHostName(config.getDatabaseHost());
+ m_database.setPort(config.getDatabasePort());
+ m_database.setDatabaseName(config.getDatabaseName());
+ m_database.setUserName(config.getDatabaseUser());
+
+ QString password = config.getDatabasePassword();
+ if (password.isEmpty()) {
+ qCritical() << "Database password not configured! Set BES_DB_PASSWORD environment variable.";
+ return;
+ }
+ m_database.setPassword(password);
+ }
+
+ // 尝试打开连接
+ m_isValid = m_database.open();
+ if (!m_isValid) {
+ qWarning() << "Failed to open database connection:" << m_database.lastError().text();
+ }
+}
+
+DatabaseConnection::~DatabaseConnection()
+{
+ if (m_database.isOpen()) {
+ m_database.close();
+ }
+
+ if (!m_connectionName.isEmpty() && QSqlDatabase::contains(m_connectionName)) {
+ QSqlDatabase::removeDatabase(m_connectionName);
+ }
+}
+
+DatabaseConnection::DatabaseConnection(DatabaseConnection&& other) noexcept
+ : m_connectionName(std::move(other.m_connectionName))
+ , m_database(std::move(other.m_database))
+ , m_autoReconnect(other.m_autoReconnect)
+ , m_isValid(other.m_isValid)
+{
+ other.m_isValid = false;
+ other.m_connectionName.clear();
+}
+
+DatabaseConnection& DatabaseConnection::operator=(DatabaseConnection&& other) noexcept
+{
+ if (this != &other) {
+ // 清理当前资源
+ if (m_database.isOpen()) {
+ m_database.close();
+ }
+ if (!m_connectionName.isEmpty() && QSqlDatabase::contains(m_connectionName)) {
+ QSqlDatabase::removeDatabase(m_connectionName);
+ }
+
+ // 移动资源
+ m_connectionName = std::move(other.m_connectionName);
+ m_database = std::move(other.m_database);
+ m_autoReconnect = other.m_autoReconnect;
+ m_isValid = other.m_isValid;
+
+ other.m_isValid = false;
+ other.m_connectionName.clear();
+ }
+ return *this;
+}
+
+bool DatabaseConnection::isValid() const
+{
+ return m_isValid && m_database.isOpen();
+}
+
+QSqlDatabase& DatabaseConnection::database()
+{
+ if (!isValid()) {
+ if (m_autoReconnect && !reconnect()) {
+ throw std::runtime_error("Database connection is not available and reconnection failed");
+ }
+ }
+ return m_database;
+}
+
+const QSqlDatabase& DatabaseConnection::database() const
+{
+ if (!isValid()) {
+ throw std::runtime_error("Database connection is not available");
+ }
+ return m_database;
+}
+
+std::unique_ptr DatabaseConnection::executeQuery(const QString& sql)
+{
+ auto query = std::make_unique(database());
+
+ if (!query->exec(sql)) {
+ qWarning() << "Query execution failed:" << query->lastError().text();
+ qWarning() << "SQL:" << sql;
+ }
+
+ return query;
+}
+
+std::unique_ptr DatabaseConnection::executePreparedQuery(const QString& sql,
+ const QVariantList& bindings)
+{
+ auto query = std::make_unique(database());
+
+ if (!query->prepare(sql)) {
+ qWarning() << "Query preparation failed:" << query->lastError().text();
+ qWarning() << "SQL:" << sql;
+ return query;
+ }
+
+ // 绑定参数
+ for (const auto& binding : bindings) {
+ query->addBindValue(binding);
+ }
+
+ if (!query->exec()) {
+ qWarning() << "Prepared query execution failed:" << query->lastError().text();
+ qWarning() << "SQL:" << sql;
+ }
+
+ return query;
+}
+
+bool DatabaseConnection::beginTransaction()
+{
+ if (!isValid()) {
+ return false;
+ }
+ return m_database.transaction();
+}
+
+bool DatabaseConnection::commitTransaction()
+{
+ if (!isValid()) {
+ return false;
+ }
+ return m_database.commit();
+}
+
+bool DatabaseConnection::rollbackTransaction()
+{
+ if (!isValid()) {
+ return false;
+ }
+ return m_database.rollback();
+}
+
+QSqlError DatabaseConnection::lastError() const
+{
+ return m_database.lastError();
+}
+
+bool DatabaseConnection::reconnect()
+{
+ if (m_database.isOpen()) {
+ m_database.close();
+ }
+
+ m_isValid = m_database.open();
+ if (!m_isValid) {
+ qWarning() << "Reconnection failed:" << m_database.lastError().text();
+ } else {
+ qDebug() << "Database reconnection successful for:" << m_connectionName;
+ }
+
+ return m_isValid;
+}
+
+// DatabaseManager 实现
+
+std::unique_ptr DatabaseManager::m_instance = nullptr;
+std::mutex DatabaseManager::m_instanceMutex;
+
+DatabaseManager& DatabaseManager::getInstance()
+{
+ std::lock_guard lock(m_instanceMutex);
+ if (!m_instance) {
+ m_instance.reset(new DatabaseManager());
+ }
+ return *m_instance;
+}
+
+DatabaseManager::DatabaseManager(QObject* parent)
+ : QObject(parent)
+ , m_maxConnections(10)
+ , m_connectionCounter(0)
+ , m_initialized(false)
+ , m_databaseAvailable(false)
+ , m_configManager(&ConfigManager::getInstance())
+ , m_totalConnectionsCreated(0)
+ , m_totalQueriesExecuted(0)
+ , m_failedConnections(0)
+{
+ // 私有构造函数
+}
+
+DatabaseManager::~DatabaseManager()
+{
+ closeAllConnections();
+}
+
+bool DatabaseManager::initialize(int maxConnections)
+{
+ std::lock_guard lock(m_mutex);
+
+ if (m_initialized) {
+ qWarning() << "DatabaseManager already initialized";
+ return true;
+ }
+
+ m_maxConnections = maxConnections;
+
+ // 确保配置管理器已初始化
+ if (!m_configManager->contains("database/host")) {
+ if (!m_configManager->initialize()) {
+ qCritical() << "Failed to initialize ConfigManager";
+ return false;
+ }
+ }
+
+ // 测试初始连接
+ auto testConnection = getConnection("test_connection");
+ if (testConnection && testConnection->isValid()) {
+ m_databaseAvailable = true;
+ qDebug() << "Database is available";
+ } else {
+ m_databaseAvailable = false;
+ qWarning() << "Database is not available";
+ }
+
+ // 启动健康检查
+ startHealthCheckTimer();
+
+ m_initialized = true;
+
+ emit databaseAvailabilityChanged(m_databaseAvailable);
+
+ qDebug() << "DatabaseManager initialized with max connections:" << m_maxConnections;
+ return true;
+}
+
+std::unique_ptr DatabaseManager::getConnection(const QString& connectionName)
+{
+ std::unique_ptr connection;
+
+ {
+ std::lock_guard lock(m_mutex);
+
+ QString actualConnectionName = connectionName.isEmpty() ?
+ generateConnectionName() : connectionName;
+
+ // 检查是否超过最大连接数
+ if (m_activeConnections.size() >= static_cast(m_maxConnections)) {
+ qWarning() << "Maximum connections reached:" << m_maxConnections;
+ return nullptr;
+ }
+
+ connection = std::make_unique(actualConnectionName);
+
+ if (connection->isValid()) {
+ m_activeConnections.push_back(actualConnectionName);
+ ++m_totalConnectionsCreated;
+ } else {
+ ++m_failedConnections;
+ return nullptr;
+ }
+ }
+
+ // 发送状态更新信号
+ emit poolStatusChanged(static_cast(m_activeConnections.size()), m_maxConnections);
+
+ return connection;
+}
+
+bool DatabaseManager::testConnection()
+{
+ auto connection = getConnection("health_check");
+ if (!connection || !connection->isValid()) {
+ return false;
+ }
+
+ auto query = connection->executeQuery("SELECT 1");
+ return query && query->next();
+}
+
+QString DatabaseManager::getPoolStatistics() const
+{
+ std::lock_guard lock(m_statsMutex);
+
+ return QString("DatabaseManager Statistics:\n"
+ "- Active connections: %1/%2\n"
+ "- Total connections created: %3\n"
+ "- Total queries executed: %4\n"
+ "- Failed connections: %5\n"
+ "- Database available: %6")
+ .arg(m_activeConnections.size())
+ .arg(m_maxConnections)
+ .arg(m_totalConnectionsCreated)
+ .arg(m_totalQueriesExecuted)
+ .arg(m_failedConnections)
+ .arg(m_databaseAvailable ? "Yes" : "No");
+}
+
+void DatabaseManager::closeAllConnections()
+{
+ std::lock_guard lock(m_mutex);
+
+ // 移除所有活跃连接
+ for (const auto& connectionName : m_activeConnections) {
+ if (QSqlDatabase::contains(connectionName)) {
+ QSqlDatabase::removeDatabase(connectionName);
+ }
+ }
+
+ m_activeConnections.clear();
+ m_availableConnections.clear();
+
+ qDebug() << "All database connections closed";
+}
+
+bool DatabaseManager::isDatabaseAvailable() const
+{
+ std::lock_guard lock(m_mutex);
+ return m_databaseAvailable;
+}
+
+void DatabaseManager::performHealthCheck()
+{
+ bool wasAvailable = m_databaseAvailable;
+ m_databaseAvailable = testConnection();
+
+ if (wasAvailable != m_databaseAvailable) {
+ emit databaseAvailabilityChanged(m_databaseAvailable);
+ qDebug() << "Database availability changed to:" << m_databaseAvailable;
+ }
+
+ // 清理失效的连接
+ cleanupIdleConnections();
+}
+
+void DatabaseManager::cleanupIdleConnections()
+{
+ std::lock_guard lock(m_mutex);
+
+ // 移除无效的连接名称
+ auto it = std::remove_if(m_activeConnections.begin(), m_activeConnections.end(),
+ [](const QString& connectionName) {
+ if (!QSqlDatabase::contains(connectionName)) {
+ return true;
+ }
+ QSqlDatabase db = QSqlDatabase::database(connectionName);
+ return !db.isOpen();
+ });
+
+ if (it != m_activeConnections.end()) {
+ int cleaned = static_cast(std::distance(it, m_activeConnections.end()));
+ m_activeConnections.erase(it, m_activeConnections.end());
+ qDebug() << "Cleaned up" << cleaned << "idle connections";
+
+ emit poolStatusChanged(static_cast(m_activeConnections.size()), m_maxConnections);
+ }
+}
+
+QString DatabaseManager::generateConnectionName()
+{
+ return QString("connection_%1_%2")
+ .arg(reinterpret_cast(QThread::currentThreadId()))
+ .arg(++m_connectionCounter);
+}
+
+void DatabaseManager::startHealthCheckTimer()
+{
+ m_healthCheckTimer = std::make_unique(this);
+ connect(m_healthCheckTimer.get(), &QTimer::timeout,
+ this, &DatabaseManager::performHealthCheck);
+
+ // 每30秒检查一次
+ m_healthCheckTimer->start(30000);
+}
+
+// DatabaseTransaction 实现
+
+DatabaseTransaction::DatabaseTransaction(DatabaseConnection& connection)
+ : m_connection(connection)
+ , m_committed(false)
+ , m_active(false)
+{
+ m_active = m_connection.beginTransaction();
+ if (!m_active) {
+ qWarning() << "Failed to begin transaction:" << m_connection.lastError().text();
+ }
+}
+
+DatabaseTransaction::~DatabaseTransaction()
+{
+ if (m_active && !m_committed) {
+ // 自动回滚未提交的事务
+ rollback();
+ }
+}
+
+bool DatabaseTransaction::commit()
+{
+ if (!m_active || m_committed) {
+ return false;
+ }
+
+ bool success = m_connection.commitTransaction();
+ if (success) {
+ m_committed = true;
+ m_active = false;
+ } else {
+ qWarning() << "Failed to commit transaction:" << m_connection.lastError().text();
+ }
+
+ return success;
+}
+
+bool DatabaseTransaction::rollback()
+{
+ if (!m_active) {
+ return false;
+ }
+
+ bool success = m_connection.rollbackTransaction();
+ m_active = false;
+
+ if (!success) {
+ qWarning() << "Failed to rollback transaction:" << m_connection.lastError().text();
+ }
+
+ return success;
+}
+
+bool DatabaseTransaction::isActive() const
+{
+ return m_active;
+}
\ No newline at end of file
diff --git a/src/Client/src/ui/components/DeviceListPanel.cpp b/src/Client/src/ui/components/DeviceListPanel.cpp
index 2403be87..24d6ea0f 100644
--- a/src/Client/src/ui/components/DeviceListPanel.cpp
+++ b/src/Client/src/ui/components/DeviceListPanel.cpp
@@ -101,40 +101,54 @@ void DeviceListPanel::setupUI()
// 搜索和过滤区域已删除
// === 操作按钮区域 ===
- m_buttonLayout = new QHBoxLayout();
-
+ // 创建垂直布局容器用于两行按钮
+ QVBoxLayout* buttonContainerLayout = new QVBoxLayout();
+ buttonContainerLayout->setSpacing(8);
+
+ // 第一行:添加设备按钮
+ QHBoxLayout* addButtonsLayout = new QHBoxLayout();
+ addButtonsLayout->setSpacing(10);
+
m_addUAVButton = new QPushButton("🚁 +无人机");
- m_addUAVButton->setMaximumHeight(60); // 调大按钮
- m_addUAVButton->setMaximumWidth(110); // 合理调整按钮宽度
- m_addUAVButton->setMinimumWidth(110); // 设置最小宽度确保文字显示完整
+ m_addUAVButton->setMinimumSize(100, 40); // 统一尺寸
+ m_addUAVButton->setMaximumSize(120, 40); // 允许适度拉伸
+ m_addUAVButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_addUAVButton->setToolTip("添加新的无人机设备");
-
+
m_addDogButton = new QPushButton("🐕 +机器狗");
- m_addDogButton->setMaximumHeight(60); // 调大按钮
- m_addDogButton->setMaximumWidth(110); // 合理调整按钮宽度
- m_addDogButton->setMinimumWidth(110); // 设置最小宽度确保文字显示完整
+ m_addDogButton->setMinimumSize(100, 40); // 统一尺寸
+ m_addDogButton->setMaximumSize(120, 40); // 允许适度拉伸
+ m_addDogButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_addDogButton->setToolTip("添加新的机器狗设备");
-
+
+ addButtonsLayout->addWidget(m_addUAVButton);
+ addButtonsLayout->addWidget(m_addDogButton);
+
+ // 第二行:管理按钮
+ QHBoxLayout* manageButtonsLayout = new QHBoxLayout();
+ manageButtonsLayout->setSpacing(10);
+
m_deleteDeviceButton = new QPushButton("🗑️ 删除");
- m_deleteDeviceButton->setMaximumHeight(60);
- m_deleteDeviceButton->setMaximumWidth(90); // 合理调整按钮宽度
- m_deleteDeviceButton->setMinimumWidth(90); // 设置最小宽度确保文字显示完整
- m_deleteDeviceButton->setToolTip("删除现有设备");
-
- m_refreshButton = new QPushButton("🔄");
- m_refreshButton->setMaximumHeight(50); // 调大刷新按钮
- m_refreshButton->setMaximumWidth(50); // 保持紧凑的刷新按钮
- m_refreshButton->setMinimumWidth(50); // 设置最小宽度
+ m_deleteDeviceButton->setMinimumSize(80, 40); // 统一尺寸
+ m_deleteDeviceButton->setMaximumSize(100, 40); // 允许适度拉伸
+ m_deleteDeviceButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ m_deleteDeviceButton->setToolTip("删除选中的设备");
+
+ m_refreshButton = new QPushButton("🔄 刷新");
+ m_refreshButton->setMinimumSize(80, 40); // 统一尺寸,增加文字
+ m_refreshButton->setMaximumSize(100, 40); // 允许适度拉伸
+ m_refreshButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_refreshButton->setToolTip("刷新设备列表");
-
- // 添加按钮间距
- m_buttonLayout->addWidget(m_addUAVButton);
- m_buttonLayout->addSpacing(5); // 添加5px间距
- m_buttonLayout->addWidget(m_addDogButton);
- m_buttonLayout->addSpacing(5); // 添加5px间距
- m_buttonLayout->addWidget(m_deleteDeviceButton); // 添加删除按钮
- m_buttonLayout->addStretch(); // 弹性空间
- m_buttonLayout->addWidget(m_refreshButton);
+
+ manageButtonsLayout->addWidget(m_deleteDeviceButton);
+ manageButtonsLayout->addWidget(m_refreshButton);
+
+ // 组装按钮布局
+ buttonContainerLayout->addLayout(addButtonsLayout);
+ buttonContainerLayout->addLayout(manageButtonsLayout);
+
+ // 保持原有的m_buttonLayout变量,但现在它指向容器布局
+ m_buttonLayout = buttonContainerLayout;
// === 设备列表滚动区域 ===
m_scrollArea = new QScrollArea();
diff --git a/src/Client/src/ui/components/RightFunctionPanel.cpp b/src/Client/src/ui/components/RightFunctionPanel.cpp
index cc5d7820..d934c2d5 100644
--- a/src/Client/src/ui/components/RightFunctionPanel.cpp
+++ b/src/Client/src/ui/components/RightFunctionPanel.cpp
@@ -7,6 +7,7 @@
*/
#include "ui/components/RightFunctionPanel.h"
+#include "utils/SystemLogger.h"
#include
#include
#include
@@ -213,60 +214,73 @@ void RightFunctionPanel::setupBattlefieldExplorationModule()
m_explorationCard = new ModuleCard("🎯 战场探索", "🎯", this);
m_explorationCard->setObjectName("ModuleCard");
m_explorationCard->setProperty("data-module", "battlefield");
-
- // 设备选择器 - 全新设计
- QWidget *deviceSelectorWidget = new QWidget();
- deviceSelectorWidget->setObjectName("device-selector");
- QHBoxLayout *deviceLayout = new QHBoxLayout(deviceSelectorWidget);
- deviceLayout->setSpacing(16); // 增加设备卡片间距
- deviceLayout->setContentsMargins(12, 12, 12, 12); // 增加容器内边距
-
- m_robotDogCard = new RightDeviceCard("🐕 机器狗-01", "", this);
- m_droneCard = new RightDeviceCard("🚁 侦察机-01", "", 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);
- m_explorationCard->addContent(deviceSelectorWidget);
-
- // 主要功能按钮 - 突出显示
- m_mappingBtn = new QPushButton("🗺️ 开始建图");
- m_mappingBtn->setObjectName("FunctionBtn");
- m_mappingBtn->setProperty("class", "primary-large");
- m_mappingBtn->setMinimumHeight(55); // 与样式表中的设置保持一致
- m_mappingBtn->setEnabled(false);
- connect(m_mappingBtn, &QPushButton::clicked, this, &RightFunctionPanel::onMappingToggle);
- m_explorationCard->addContent(m_mappingBtn);
-
- // 次要功能按钮 - 三列布局
- QWidget *secondaryWidget = new QWidget();
- QHBoxLayout *secondaryLayout = new QHBoxLayout(secondaryWidget);
- secondaryLayout->setSpacing(12); // 增加按钮间距
- secondaryLayout->setContentsMargins(0, 12, 0, 0); // 增加上边距
-
- m_navigationBtn = new QPushButton("🧭 导航");
- m_photoBtn = new QPushButton("📸 传输");
- m_recognitionBtn = new QPushButton("👁️ 识别");
-
- // 设置次要按钮样式
- QList secondaryBtns = {m_navigationBtn, m_photoBtn, m_recognitionBtn};
- for(auto btn : secondaryBtns) {
- btn->setObjectName("FunctionBtn");
- btn->setProperty("class", "secondary-small");
- btn->setMinimumHeight(42); // 与样式表中的设置保持一致
- btn->setEnabled(false);
- }
-
- connect(m_navigationBtn, &QPushButton::clicked, this, &RightFunctionPanel::onNavigationToggle);
- connect(m_photoBtn, &QPushButton::clicked, this, &RightFunctionPanel::onPhotoTransmissionToggle);
- connect(m_recognitionBtn, &QPushButton::clicked, this, &RightFunctionPanel::onPersonRecognitionToggle);
-
- secondaryLayout->addWidget(m_navigationBtn);
- secondaryLayout->addWidget(m_photoBtn);
- secondaryLayout->addWidget(m_recognitionBtn);
- m_explorationCard->addContent(secondaryWidget);
+
+ // 简化设计:只显示两个主要功能入口按钮
+ QWidget *mainControlWidget = new QWidget();
+ mainControlWidget->setObjectName("main-control-widget");
+ QVBoxLayout *mainControlLayout = new QVBoxLayout(mainControlWidget);
+ mainControlLayout->setSpacing(20);
+ mainControlLayout->setContentsMargins(16, 16, 16, 16);
+
+ // 无人机控制按钮
+ m_droneControlBtn = new QPushButton("🚁 无人机控制");
+ m_droneControlBtn->setObjectName("FunctionBtn");
+ m_droneControlBtn->setProperty("class", "primary-large");
+ m_droneControlBtn->setMinimumHeight(65);
+ m_droneControlBtn->setStyleSheet(
+ "QPushButton {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #0078d4, stop:1 #106ebe);"
+ " color: white;"
+ " font-size: 18px;"
+ " font-weight: bold;"
+ " border: 2px solid #0078d4;"
+ " border-radius: 12px;"
+ " padding: 16px;"
+ "}"
+ "QPushButton:hover {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #106ebe, stop:1 #005a9f);"
+ " border-color: #106ebe;"
+ "}"
+ "QPushButton:pressed {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #005a9f, stop:1 #004578);"
+ "}"
+ );
+ connect(m_droneControlBtn, &QPushButton::clicked, this, &RightFunctionPanel::onDroneControlClicked);
+
+ // 机器狗控制按钮
+ m_robotDogControlBtn = new QPushButton("🐕 机器狗控制");
+ m_robotDogControlBtn->setObjectName("FunctionBtn");
+ m_robotDogControlBtn->setProperty("class", "primary-large");
+ m_robotDogControlBtn->setMinimumHeight(65);
+ m_robotDogControlBtn->setStyleSheet(
+ "QPushButton {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #16a085, stop:1 #138d75);"
+ " color: white;"
+ " font-size: 18px;"
+ " font-weight: bold;"
+ " border: 2px solid #16a085;"
+ " border-radius: 12px;"
+ " padding: 16px;"
+ "}"
+ "QPushButton:hover {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #138d75, stop:1 #117a65);"
+ " border-color: #138d75;"
+ "}"
+ "QPushButton:pressed {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #117a65, stop:1 #0e6b5d);"
+ "}"
+ );
+ connect(m_robotDogControlBtn, &QPushButton::clicked, this, &RightFunctionPanel::onRobotDogControlClicked);
+
+ mainControlLayout->addWidget(m_droneControlBtn);
+ mainControlLayout->addWidget(m_robotDogControlBtn);
+ m_explorationCard->addContent(mainControlWidget);
m_mainLayout->addWidget(m_explorationCard);
}
@@ -277,47 +291,101 @@ void RightFunctionPanel::setupIntelligenceModule()
m_intelligenceCard->setObjectName("ModuleCard");
m_intelligenceCard->setProperty("data-module", "intelligence");
- // 情报传达说明
- QLabel *descLabel = new QLabel("🎯 远程音频控制系统");
+ // 情报传达说明 - 统一样式
+ QLabel *descLabel = new QLabel("🎯 远程控制系统");
descLabel->setObjectName("intelligence-description");
descLabel->setAlignment(Qt::AlignCenter);
- descLabel->setStyleSheet("color: #00a8ff; font-size: 14px; font-weight: bold; padding: 8px;");
+ descLabel->setStyleSheet(
+ "color: #2196F3; "
+ "font-size: 14px; "
+ "font-weight: bold; "
+ "padding: 10px; "
+ "margin-bottom: 8px;"
+ );
m_intelligenceCard->addContent(descLabel);
- // 主功能按钮 - 打开音频控制界面
- m_voiceCallBtn = new QPushButton("🔊 打开音频控制界面");
+ // 按钮布局容器 - 增加间距
+ QWidget *buttonWidget = new QWidget();
+ QVBoxLayout *buttonLayout = new QVBoxLayout(buttonWidget);
+ buttonLayout->setSpacing(20); // 12px → 20px 增强分离感
+ buttonLayout->setContentsMargins(8, 12, 8, 12); // 增加容器边距
+
+ // 主要功能:音频控制按钮 - 提升优先级
+ m_voiceCallBtn = new QPushButton("🔊 音频控制模块");
m_voiceCallBtn->setObjectName("FunctionBtn");
m_voiceCallBtn->setProperty("class", "primary-large");
- m_voiceCallBtn->setMinimumHeight(55);
+ m_voiceCallBtn->setMinimumHeight(65); // 55px → 65px 突出主要功能
m_voiceCallBtn->setStyleSheet(
"QPushButton {"
" background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
- " stop:0 #00a8ff, stop:1 #0078d4);"
+ " stop:0 #2196F3, stop:1 #1976D2);" // 统一蓝色主题
" color: white;"
- " font-size: 16px;"
+ " font-size: 17px;" // 16px → 17px 提升可读性
" font-weight: bold;"
- " border: 2px solid #00a8ff;"
+ " border: 2px solid #2196F3;"
" border-radius: 8px;"
- " padding: 12px;"
+ " padding: 16px;" // 12px → 16px 统一内边距
"}"
"QPushButton:hover {"
" background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
- " stop:0 #0078d4, stop:1 #005a9f);"
+ " stop:0 #1976D2, stop:1 #1565C0);"
+ " border-color: #1976D2;"
+ " transform: translateY(-1px);" // 添加微妙的悬停效果
"}"
"QPushButton:pressed {"
" background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
- " stop:0 #005a9f, stop:1 #003d6b);"
+ " stop:0 #1565C0, stop:1 #0D47A1);"
+ " transform: translateY(0px);"
+ "}"
+ );
+
+ // 辅助功能:面部灯光控制按钮 - 降低优先级
+ m_faceLightBtn = new QPushButton("💡 灯光控制模块");
+ m_faceLightBtn->setObjectName("FunctionBtn");
+ m_faceLightBtn->setProperty("class", "secondary-medium"); // primary-large → secondary-medium
+ m_faceLightBtn->setMinimumHeight(50); // 55px → 50px 体现次要地位
+ m_faceLightBtn->setStyleSheet(
+ "QPushButton {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #607D8B, stop:1 #455A64);" // 橙红色 → 中性灰蓝色
+ " color: white;"
+ " font-size: 15px;" // 16px → 15px 体现层次差异
+ " font-weight: bold;"
+ " border: 2px solid #607D8B;"
+ " border-radius: 8px;"
+ " padding: 16px;" // 统一内边距
+ "}"
+ "QPushButton:hover {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #546E7A, stop:1 #37474F);"
+ " border-color: #546E7A;"
+ " transform: translateY(-1px);"
+ "}"
+ "QPushButton:pressed {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #37474F, stop:1 #263238);"
+ " transform: translateY(0px);"
"}"
);
connect(m_voiceCallBtn, &QPushButton::clicked, this, &RightFunctionPanel::onOpenIntelligenceUI);
- m_intelligenceCard->addContent(m_voiceCallBtn);
+ connect(m_faceLightBtn, &QPushButton::clicked, this, &RightFunctionPanel::onOpenFaceLightUI);
+
+ buttonLayout->addWidget(m_voiceCallBtn);
+ buttonLayout->addWidget(m_faceLightBtn);
+ m_intelligenceCard->addContent(buttonWidget);
- // 功能介绍
- QLabel *featureLabel = new QLabel("• SSH双跳连接\n• 音频文件播放\n• 实时录音制作\n• TTS语音合成");
+ // 功能介绍 - 统一样式和间距
+ QLabel *featureLabel = new QLabel("• SSH双跳连接\n• 音频播放控制\n• 面部灯光控制\n• 实时状态监控");
featureLabel->setObjectName("feature-list");
featureLabel->setAlignment(Qt::AlignLeft);
- featureLabel->setStyleSheet("color: #b0b0b0; font-size: 12px; padding: 10px; line-height: 1.4;");
+ featureLabel->setStyleSheet(
+ "color: #90A4AE; " // #b0b0b0 → #90A4AE 与主题更协调
+ "font-size: 12px; "
+ "padding: 12px 10px; " // 增加上下边距
+ "line-height: 1.5; " // 提升行高可读性
+ "margin-top: 8px;"
+ );
m_intelligenceCard->addContent(featureLabel);
m_mainLayout->addWidget(m_intelligenceCard);
@@ -663,7 +731,7 @@ void RightFunctionPanel::applyStyles()
/* text-shadow 不支持,用边框替代发光效果 */
border: 1px solid rgba(0, 168, 255, 0.5);
}
-
+
#threat-level {
color: #ffa502;
font-size: 15px;
@@ -761,16 +829,20 @@ 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);
+ bool isDrone = deviceName.contains("无人机") || deviceName.contains("drone") || deviceName.contains("uav");
+
+ SystemLogger::getInstance()->logInfo(QString("设备选择: %1 (机器狗: %2, 无人机: %3)")
+ .arg(deviceName)
+ .arg(isRobotDog ? "是" : "否")
+ .arg(isDrone ? "是" : "否"));
+
+ // 注释掉按钮启用/禁用逻辑,因为现在使用独立的控制按钮
+ // m_mappingBtn->setEnabled(isRobotDog);
+ // m_navigationBtn->setEnabled(isRobotDog);
+ // m_photoBtn->setEnabled(!isRobotDog);
+ // m_recognitionBtn->setEnabled(!isRobotDog);
}
void RightFunctionPanel::onMappingToggle()
@@ -846,6 +918,11 @@ void RightFunctionPanel::onOpenIntelligenceUI()
emit openIntelligenceUI();
}
+void RightFunctionPanel::onOpenFaceLightUI()
+{
+ emit openFaceLightUI();
+}
+
void RightFunctionPanel::onRefreshStats()
{
emit refreshEnemyStats();
@@ -866,17 +943,27 @@ void RightFunctionPanel::onRefreshStats()
});
}
+void RightFunctionPanel::onDroneControlClicked()
+{
+ emit droneControlRequested();
+}
+
+void RightFunctionPanel::onRobotDogControlClicked()
+{
+ emit robotDogControlRequested();
+}
+
void RightFunctionPanel::onAIAnalysis()
{
emit requestAIAnalysis();
-
+
// 显示分析状态
m_aiAnalysisBtn->setText("🧠 分析中...");
m_aiAnalysisBtn->setProperty("class", "loading");
m_aiAnalysisBtn->setEnabled(false);
m_aiAnalysisBtn->style()->unpolish(m_aiAnalysisBtn);
m_aiAnalysisBtn->style()->polish(m_aiAnalysisBtn);
-
+
QTimer::singleShot(3000, [this]() {
m_aiAnalysisBtn->setText("🤖 AI分析");
m_aiAnalysisBtn->setProperty("class", "secondary-medium");
@@ -924,27 +1011,31 @@ void RightFunctionPanel::updateEnemyStats(int totalEnemies, const QString &threa
void RightFunctionPanel::updateDeviceStatus(const QString &deviceName, bool online, int battery)
{
- RightDeviceCard *deviceCard = nullptr;
+ // 设备卡片已删除,改为日志记录设备状态
+ QString deviceType;
if (deviceName.contains("机器狗") || deviceName.contains("robot") || deviceName.contains("dog")) {
- deviceCard = m_robotDogCard;
+ deviceType = "机器狗";
} else if (deviceName.contains("无人机") || deviceName.contains("drone") || deviceName.contains("uav")) {
- deviceCard = m_droneCard;
+ deviceType = "无人机";
+ } else {
+ deviceType = "未知设备";
}
-
- if (deviceCard) {
- if (online) {
- if (battery > 80) {
- deviceCard->setStatus(QString("📶 连接质量 %1%").arg(battery), QColor("#4CAF50"));
- } else if (battery > 50) {
- deviceCard->setStatus(QString("📶 连接质量 %1%").arg(battery), QColor("#8BC34A"));
- } else if (battery > 20) {
- deviceCard->setStatus(QString("⚠️ 连接质量 %1%").arg(battery), QColor("#FF8C00"));
- } else {
- deviceCard->setStatus(QString("⚠️ 连接质量 %1%").arg(battery), QColor("#DC143C"));
- }
+
+ QString statusMsg;
+ if (online) {
+ if (battery > 80) {
+ statusMsg = QString("%1 %2: 📶 连接质量 %3% (优秀)").arg(deviceType).arg(deviceName).arg(battery);
+ } else if (battery > 50) {
+ statusMsg = QString("%1 %2: 📶 连接质量 %3% (良好)").arg(deviceType).arg(deviceName).arg(battery);
+ } else if (battery > 20) {
+ statusMsg = QString("%1 %2: ⚠️ 连接质量 %3% (一般)").arg(deviceType).arg(deviceName).arg(battery);
} else {
- deviceCard->setStatus("❌ 设备离线", QColor("#78909C"));
+ statusMsg = QString("%1 %2: ⚠️ 连接质量 %3% (较差)").arg(deviceType).arg(deviceName).arg(battery);
}
+ } else {
+ statusMsg = QString("%1 %2: ❌ 设备离线").arg(deviceType).arg(deviceName);
}
+
+ SystemLogger::getInstance()->logInfo(statusMsg);
}
diff --git a/src/Client/src/ui/dialogs/DroneControlDialog.cpp b/src/Client/src/ui/dialogs/DroneControlDialog.cpp
new file mode 100644
index 00000000..0aca4901
--- /dev/null
+++ b/src/Client/src/ui/dialogs/DroneControlDialog.cpp
@@ -0,0 +1,545 @@
+/**
+ * @file DroneControlDialog.cpp
+ * @brief 无人机控制对话框实现
+ * @author Qt UI Optimizer
+ * @date 2024-07-04
+ * @version 1.0
+ */
+
+#include "ui/dialogs/DroneControlDialog.h"
+#include "styles/ModernStyleManager.h"
+
+#include
+#include
+#include
+#include
+
+DroneControlDialog::DroneControlDialog(QWidget *parent)
+ : QDialog(parent)
+ , m_mainLayout(nullptr)
+ , m_contentLayout(nullptr)
+ , m_isMappingActive(false)
+ , m_isNavigationActive(false)
+ , m_isPhotoTransmissionActive(false)
+ , m_isPersonRecognitionActive(false)
+ , m_isFlying(false)
+ , m_statusUpdateTimer(new QTimer(this))
+{
+ setupUI();
+ applyStyles();
+ connectSignals();
+
+ // 启动状态更新定时器
+ m_statusUpdateTimer->start(1000);
+}
+
+DroneControlDialog::~DroneControlDialog()
+{
+ if (m_statusUpdateTimer) {
+ m_statusUpdateTimer->stop();
+ }
+}
+
+void DroneControlDialog::setupUI()
+{
+ setWindowTitle("🚁 无人机控制中心");
+ setModal(false);
+ setMinimumSize(900, 700);
+ resize(1000, 750);
+
+ // 窗口居中显示
+ QRect screenGeometry = QApplication::desktop()->screenGeometry();
+ int x = (screenGeometry.width() - this->width()) / 2;
+ int y = (screenGeometry.height() - this->height()) / 2;
+ move(x, y);
+
+ m_mainLayout = new QVBoxLayout(this);
+ m_mainLayout->setSpacing(20);
+ m_mainLayout->setContentsMargins(20, 20, 20, 20);
+
+ // 标题
+ QLabel *titleLabel = new QLabel("🚁 无人机控制中心");
+ titleLabel->setObjectName("DialogTitle");
+ titleLabel->setAlignment(Qt::AlignCenter);
+ titleLabel->setStyleSheet(
+ "font-size: 24px; "
+ "font-weight: bold; "
+ "color: #0078d4; "
+ "padding: 10px; "
+ "border-bottom: 2px solid #0078d4; "
+ "margin-bottom: 10px;"
+ );
+ m_mainLayout->addWidget(titleLabel);
+
+ // 主内容区域
+ m_contentLayout = new QHBoxLayout();
+ m_contentLayout->setSpacing(20);
+
+ setupFlightControlModule();
+ setupMissionControlModule();
+ setupStatusMonitorModule();
+
+ m_mainLayout->addLayout(m_contentLayout);
+
+ // 底部按钮
+ QHBoxLayout *buttonLayout = new QHBoxLayout();
+ buttonLayout->addStretch();
+
+ QPushButton *closeBtn = new QPushButton("关闭");
+ closeBtn->setObjectName("CloseBtn");
+ closeBtn->setMinimumSize(100, 40);
+ connect(closeBtn, &QPushButton::clicked, this, &QDialog::close);
+
+ buttonLayout->addWidget(closeBtn);
+ m_mainLayout->addLayout(buttonLayout);
+}
+
+void DroneControlDialog::setupFlightControlModule()
+{
+ m_flightControlGroup = new QGroupBox("✈️ 飞行控制");
+ m_flightControlGroup->setObjectName("ControlGroup");
+ m_flightControlGroup->setMinimumWidth(280);
+
+ QVBoxLayout *flightLayout = new QVBoxLayout(m_flightControlGroup);
+ flightLayout->setSpacing(15);
+
+ // 基础飞行控制按钮
+ QGridLayout *basicControlLayout = new QGridLayout();
+ basicControlLayout->setSpacing(10);
+
+ m_takeoffBtn = new QPushButton("🚀 起飞");
+ m_takeoffBtn->setObjectName("PrimaryBtn");
+ m_takeoffBtn->setMinimumHeight(50);
+
+ m_landBtn = new QPushButton("🛬 降落");
+ m_landBtn->setObjectName("WarningBtn");
+ m_landBtn->setMinimumHeight(50);
+ m_landBtn->setEnabled(false);
+
+ m_hoverBtn = new QPushButton("⏸️ 悬停");
+ m_hoverBtn->setObjectName("InfoBtn");
+ m_hoverBtn->setMinimumHeight(50);
+ m_hoverBtn->setEnabled(false);
+
+ m_returnHomeBtn = new QPushButton("🏠 返航");
+ m_returnHomeBtn->setObjectName("SuccessBtn");
+ m_returnHomeBtn->setMinimumHeight(50);
+ m_returnHomeBtn->setEnabled(false);
+
+ basicControlLayout->addWidget(m_takeoffBtn, 0, 0);
+ basicControlLayout->addWidget(m_landBtn, 0, 1);
+ basicControlLayout->addWidget(m_hoverBtn, 1, 0);
+ basicControlLayout->addWidget(m_returnHomeBtn, 1, 1);
+
+ flightLayout->addLayout(basicControlLayout);
+
+ // 高度和速度控制
+ QLabel *altitudeLabel = new QLabel("飞行高度 (m):");
+ m_altitudeSlider = new QSlider(Qt::Horizontal);
+ m_altitudeSlider->setRange(1, 100);
+ m_altitudeSlider->setValue(10);
+ m_altitudeSlider->setEnabled(false);
+
+ QLabel *speedLabel = new QLabel("飞行速度 (m/s):");
+ m_speedSlider = new QSlider(Qt::Horizontal);
+ m_speedSlider->setRange(1, 20);
+ m_speedSlider->setValue(5);
+ m_speedSlider->setEnabled(false);
+
+ flightLayout->addWidget(altitudeLabel);
+ flightLayout->addWidget(m_altitudeSlider);
+ flightLayout->addWidget(speedLabel);
+ flightLayout->addWidget(m_speedSlider);
+
+ // 紧急停止按钮
+ m_emergencyStopBtn = new QPushButton("🚨 紧急停止");
+ m_emergencyStopBtn->setObjectName("DangerBtn");
+ m_emergencyStopBtn->setMinimumHeight(60);
+ m_emergencyStopBtn->setStyleSheet(
+ "QPushButton {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #e74c3c, stop:1 #c0392b);"
+ " color: white;"
+ " font-size: 16px;"
+ " font-weight: bold;"
+ " border: 2px solid #e74c3c;"
+ " border-radius: 8px;"
+ "}"
+ "QPushButton:hover {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #c0392b, stop:1 #a93226);"
+ "}"
+ );
+
+ flightLayout->addWidget(m_emergencyStopBtn);
+ flightLayout->addStretch();
+
+ m_contentLayout->addWidget(m_flightControlGroup);
+}
+
+void DroneControlDialog::setupMissionControlModule()
+{
+ m_missionControlGroup = new QGroupBox("🎯 任务控制");
+ m_missionControlGroup->setObjectName("ControlGroup");
+ m_missionControlGroup->setMinimumWidth(280);
+
+ QVBoxLayout *missionLayout = new QVBoxLayout(m_missionControlGroup);
+ missionLayout->setSpacing(15);
+
+ // 任务模式选择
+ QLabel *modeLabel = new QLabel("任务模式:");
+ m_missionModeCombo = new QComboBox();
+ m_missionModeCombo->addItems({"手动控制", "自主巡航", "目标跟踪", "区域扫描"});
+ m_missionModeCombo->setMinimumHeight(35);
+
+ missionLayout->addWidget(modeLabel);
+ missionLayout->addWidget(m_missionModeCombo);
+
+ // 功能控制按钮
+ m_mappingBtn = new QPushButton("🗺️ 开始建图");
+ m_mappingBtn->setObjectName("FunctionBtn");
+ m_mappingBtn->setMinimumHeight(50);
+ m_mappingBtn->setCheckable(true);
+
+ m_navigationBtn = new QPushButton("🧭 导航避障");
+ m_navigationBtn->setObjectName("FunctionBtn");
+ m_navigationBtn->setMinimumHeight(50);
+ m_navigationBtn->setCheckable(true);
+
+ m_photoBtn = new QPushButton("📸 照片传输");
+ m_photoBtn->setObjectName("FunctionBtn");
+ m_photoBtn->setMinimumHeight(50);
+ m_photoBtn->setCheckable(true);
+
+ m_recognitionBtn = new QPushButton("👁️ 人物识别");
+ m_recognitionBtn->setObjectName("FunctionBtn");
+ m_recognitionBtn->setMinimumHeight(50);
+ m_recognitionBtn->setCheckable(true);
+
+ missionLayout->addWidget(m_mappingBtn);
+ missionLayout->addWidget(m_navigationBtn);
+ missionLayout->addWidget(m_photoBtn);
+ missionLayout->addWidget(m_recognitionBtn);
+ missionLayout->addStretch();
+
+ m_contentLayout->addWidget(m_missionControlGroup);
+}
+
+void DroneControlDialog::setupStatusMonitorModule()
+{
+ m_statusGroup = new QGroupBox("📊 状态监控");
+ m_statusGroup->setObjectName("ControlGroup");
+ m_statusGroup->setMinimumWidth(320);
+
+ QVBoxLayout *statusLayout = new QVBoxLayout(m_statusGroup);
+ statusLayout->setSpacing(15);
+
+ // 电池状态
+ QHBoxLayout *batteryLayout = new QHBoxLayout();
+ m_batteryLabel = new QLabel("电池电量:");
+ m_batteryProgress = new QProgressBar();
+ m_batteryProgress->setRange(0, 100);
+ m_batteryProgress->setValue(85);
+ m_batteryProgress->setTextVisible(true);
+ m_batteryProgress->setFormat("%p%");
+
+ batteryLayout->addWidget(m_batteryLabel);
+ batteryLayout->addWidget(m_batteryProgress);
+ statusLayout->addLayout(batteryLayout);
+
+ // 飞行参数
+ QGridLayout *paramLayout = new QGridLayout();
+ paramLayout->addWidget(new QLabel("飞行高度:"), 0, 0);
+ m_altitudeLabel = new QLabel("0.0 m");
+ m_altitudeLabel->setStyleSheet("font-weight: bold; color: #0078d4;");
+ paramLayout->addWidget(m_altitudeLabel, 0, 1);
+
+ paramLayout->addWidget(new QLabel("飞行速度:"), 1, 0);
+ m_speedLabel = new QLabel("0.0 m/s");
+ m_speedLabel->setStyleSheet("font-weight: bold; color: #0078d4;");
+ paramLayout->addWidget(m_speedLabel, 1, 1);
+
+ paramLayout->addWidget(new QLabel("GPS状态:"), 2, 0);
+ m_gpsLabel = new QLabel("🔴 未连接");
+ paramLayout->addWidget(m_gpsLabel, 2, 1);
+
+ paramLayout->addWidget(new QLabel("连接状态:"), 3, 0);
+ m_connectionLabel = new QLabel("🟢 已连接");
+ paramLayout->addWidget(m_connectionLabel, 3, 1);
+
+ statusLayout->addLayout(paramLayout);
+
+ // 日志显示
+ QLabel *logLabel = new QLabel("系统日志:");
+ m_logTextEdit = new QTextEdit();
+ m_logTextEdit->setMaximumHeight(200);
+ m_logTextEdit->setReadOnly(true);
+ m_logTextEdit->append(QString("[%1] 无人机控制系统启动").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ m_logTextEdit->append(QString("[%1] 等待连接无人机...").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+
+ statusLayout->addWidget(logLabel);
+ statusLayout->addWidget(m_logTextEdit);
+
+ m_contentLayout->addWidget(m_statusGroup);
+}
+
+void DroneControlDialog::applyStyles()
+{
+ // 应用现代样式管理器
+ ModernStyleManager* styleManager = ModernStyleManager::getInstance();
+
+ // 应用按钮样式
+ styleManager->applyButtonStyle(m_takeoffBtn, ModernStyleManager::ButtonStyle::Primary);
+ styleManager->applyButtonStyle(m_landBtn, ModernStyleManager::ButtonStyle::Warning);
+ styleManager->applyButtonStyle(m_hoverBtn, ModernStyleManager::ButtonStyle::Info);
+ styleManager->applyButtonStyle(m_returnHomeBtn, ModernStyleManager::ButtonStyle::Success);
+ styleManager->applyButtonStyle(m_emergencyStopBtn, ModernStyleManager::ButtonStyle::Danger);
+
+ // 设置对话框样式
+ setStyleSheet(
+ "QDialog {"
+ " background-color: #f8f9fa;"
+ " border: 1px solid #dee2e6;"
+ "}"
+ "QGroupBox {"
+ " font-size: 16px;"
+ " font-weight: bold;"
+ " color: #495057;"
+ " border: 2px solid #dee2e6;"
+ " border-radius: 8px;"
+ " margin-top: 10px;"
+ " padding-top: 10px;"
+ "}"
+ "QGroupBox::title {"
+ " subcontrol-origin: margin;"
+ " left: 10px;"
+ " padding: 0 8px 0 8px;"
+ " background-color: #f8f9fa;"
+ "}"
+ "QSlider::groove:horizontal {"
+ " border: 1px solid #bbb;"
+ " background: white;"
+ " height: 10px;"
+ " border-radius: 4px;"
+ "}"
+ "QSlider::handle:horizontal {"
+ " background: #0078d4;"
+ " border: 1px solid #5c5c5c;"
+ " width: 18px;"
+ " margin: -2px 0;"
+ " border-radius: 3px;"
+ "}"
+ "QProgressBar {"
+ " border: 2px solid #dee2e6;"
+ " border-radius: 5px;"
+ " text-align: center;"
+ " font-weight: bold;"
+ "}"
+ "QProgressBar::chunk {"
+ " background-color: #28a745;"
+ " border-radius: 3px;"
+ "}"
+ "QTextEdit {"
+ " border: 1px solid #dee2e6;"
+ " border-radius: 4px;"
+ " background-color: white;"
+ " font-family: 'Consolas', monospace;"
+ " font-size: 12px;"
+ "}"
+ );
+}
+
+void DroneControlDialog::connectSignals()
+{
+ // 飞行控制信号连接
+ connect(m_takeoffBtn, &QPushButton::clicked, this, &DroneControlDialog::onTakeoffClicked);
+ connect(m_landBtn, &QPushButton::clicked, this, &DroneControlDialog::onLandClicked);
+ connect(m_hoverBtn, &QPushButton::clicked, this, &DroneControlDialog::onHoverClicked);
+ connect(m_returnHomeBtn, &QPushButton::clicked, this, &DroneControlDialog::onReturnHomeClicked);
+ connect(m_emergencyStopBtn, &QPushButton::clicked, this, &DroneControlDialog::onEmergencyStop);
+
+ // 任务控制信号连接
+ connect(m_mappingBtn, &QPushButton::clicked, this, &DroneControlDialog::onMappingToggle);
+ connect(m_navigationBtn, &QPushButton::clicked, this, &DroneControlDialog::onNavigationToggle);
+ connect(m_photoBtn, &QPushButton::clicked, this, &DroneControlDialog::onPhotoTransmissionToggle);
+ connect(m_recognitionBtn, &QPushButton::clicked, this, &DroneControlDialog::onPersonRecognitionToggle);
+
+ // 状态更新定时器
+ connect(m_statusUpdateTimer, &QTimer::timeout, [this]() {
+ // 模拟状态更新
+ static int counter = 0;
+ counter++;
+
+ if (m_isFlying) {
+ // 模拟电池消耗
+ int currentBattery = m_batteryProgress->value();
+ if (currentBattery > 0 && counter % 10 == 0) {
+ m_batteryProgress->setValue(currentBattery - 1);
+ }
+
+ // 更新电池颜色
+ if (currentBattery > 50) {
+ m_batteryProgress->setStyleSheet("QProgressBar::chunk { background-color: #28a745; }");
+ } else if (currentBattery > 20) {
+ m_batteryProgress->setStyleSheet("QProgressBar::chunk { background-color: #ffc107; }");
+ } else {
+ m_batteryProgress->setStyleSheet("QProgressBar::chunk { background-color: #dc3545; }");
+ }
+ }
+ });
+}
+
+// 槽函数实现
+void DroneControlDialog::onTakeoffClicked()
+{
+ m_isFlying = true;
+ m_takeoffBtn->setEnabled(false);
+ m_landBtn->setEnabled(true);
+ m_hoverBtn->setEnabled(true);
+ m_returnHomeBtn->setEnabled(true);
+ m_altitudeSlider->setEnabled(true);
+ m_speedSlider->setEnabled(true);
+
+ m_logTextEdit->append(QString("[%1] 无人机起飞中...").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ m_gpsLabel->setText("🟢 GPS已锁定");
+
+ // 模拟起飞过程
+ QTimer::singleShot(2000, [this]() {
+ m_logTextEdit->append(QString("[%1] 无人机起飞成功,当前高度: %2m").arg(
+ QDateTime::currentDateTime().toString("hh:mm:ss")).arg(m_altitudeSlider->value()));
+ updateDroneStatus(m_batteryProgress->value(), m_altitudeSlider->value(), m_speedSlider->value());
+ });
+}
+
+void DroneControlDialog::onLandClicked()
+{
+ m_isFlying = false;
+ m_takeoffBtn->setEnabled(true);
+ m_landBtn->setEnabled(false);
+ m_hoverBtn->setEnabled(false);
+ m_returnHomeBtn->setEnabled(false);
+ m_altitudeSlider->setEnabled(false);
+ m_speedSlider->setEnabled(false);
+
+ // 停止所有任务
+ if (m_isMappingActive) onMappingToggle();
+ if (m_isNavigationActive) onNavigationToggle();
+ if (m_isPhotoTransmissionActive) onPhotoTransmissionToggle();
+ if (m_isPersonRecognitionActive) onPersonRecognitionToggle();
+
+ m_logTextEdit->append(QString("[%1] 无人机降落中...").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+
+ QTimer::singleShot(3000, [this]() {
+ m_logTextEdit->append(QString("[%1] 无人机安全降落").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ updateDroneStatus(m_batteryProgress->value(), 0.0, 0.0);
+ });
+}
+
+void DroneControlDialog::onHoverClicked()
+{
+ m_logTextEdit->append(QString("[%1] 无人机进入悬停模式").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ updateDroneStatus(m_batteryProgress->value(), m_altitudeSlider->value(), 0.0);
+}
+
+void DroneControlDialog::onReturnHomeClicked()
+{
+ m_logTextEdit->append(QString("[%1] 无人机开始返航").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+
+ // 停止所有任务
+ if (m_isMappingActive) onMappingToggle();
+ if (m_isNavigationActive) onNavigationToggle();
+ if (m_isPhotoTransmissionActive) onPhotoTransmissionToggle();
+ if (m_isPersonRecognitionActive) onPersonRecognitionToggle();
+
+ QTimer::singleShot(5000, [this]() {
+ m_logTextEdit->append(QString("[%1] 无人机返航完成").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ onLandClicked();
+ });
+}
+
+void DroneControlDialog::onEmergencyStop()
+{
+ QMessageBox::StandardButton reply = QMessageBox::warning(this, "紧急停止",
+ "确定要执行紧急停止吗?这将立即停止所有操作!",
+ QMessageBox::Yes | QMessageBox::No);
+
+ if (reply == QMessageBox::Yes) {
+ m_logTextEdit->append(QString("[%1] 🚨 执行紧急停止!").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ onLandClicked();
+ }
+}
+
+void DroneControlDialog::onMappingToggle()
+{
+ m_isMappingActive = !m_isMappingActive;
+
+ if (m_isMappingActive) {
+ m_mappingBtn->setText("🗺️ 停止建图");
+ m_mappingBtn->setStyleSheet("background-color: #dc3545; color: white;");
+ m_logTextEdit->append(QString("[%1] 开始自主建图").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit startMapping();
+ } else {
+ m_mappingBtn->setText("🗺️ 开始建图");
+ m_mappingBtn->setStyleSheet("");
+ m_logTextEdit->append(QString("[%1] 停止自主建图").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit stopMapping();
+ }
+}
+
+void DroneControlDialog::onNavigationToggle()
+{
+ m_isNavigationActive = !m_isNavigationActive;
+
+ if (m_isNavigationActive) {
+ m_navigationBtn->setText("🧭 停止导航");
+ m_navigationBtn->setStyleSheet("background-color: #dc3545; color: white;");
+ m_logTextEdit->append(QString("[%1] 开始导航避障").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit startNavigation();
+ } else {
+ m_navigationBtn->setText("🧭 导航避障");
+ m_navigationBtn->setStyleSheet("");
+ m_logTextEdit->append(QString("[%1] 停止导航避障").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit stopNavigation();
+ }
+}
+
+void DroneControlDialog::onPhotoTransmissionToggle()
+{
+ m_isPhotoTransmissionActive = !m_isPhotoTransmissionActive;
+
+ if (m_isPhotoTransmissionActive) {
+ m_photoBtn->setText("📸 停止传输");
+ m_photoBtn->setStyleSheet("background-color: #dc3545; color: white;");
+ m_logTextEdit->append(QString("[%1] 开始照片传输").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit startPhotoTransmission();
+ } else {
+ m_photoBtn->setText("📸 照片传输");
+ m_photoBtn->setStyleSheet("");
+ m_logTextEdit->append(QString("[%1] 停止照片传输").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit stopPhotoTransmission();
+ }
+}
+
+void DroneControlDialog::onPersonRecognitionToggle()
+{
+ m_isPersonRecognitionActive = !m_isPersonRecognitionActive;
+
+ if (m_isPersonRecognitionActive) {
+ m_recognitionBtn->setText("👁️ 停止识别");
+ m_recognitionBtn->setStyleSheet("background-color: #dc3545; color: white;");
+ m_logTextEdit->append(QString("[%1] 开始人物识别").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit startPersonRecognition();
+ } else {
+ m_recognitionBtn->setText("👁️ 人物识别");
+ m_recognitionBtn->setStyleSheet("");
+ m_logTextEdit->append(QString("[%1] 停止人物识别").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit stopPersonRecognition();
+ }
+}
+
+void DroneControlDialog::updateDroneStatus(int battery, double altitude, double speed)
+{
+ m_batteryProgress->setValue(battery);
+ m_altitudeLabel->setText(QString("%1 m").arg(altitude, 0, 'f', 1));
+ m_speedLabel->setText(QString("%1 m/s").arg(speed, 0, 'f', 1));
+}
diff --git a/src/Client/src/ui/dialogs/RobotDogControlDialog.cpp b/src/Client/src/ui/dialogs/RobotDogControlDialog.cpp
new file mode 100644
index 00000000..1781c85c
--- /dev/null
+++ b/src/Client/src/ui/dialogs/RobotDogControlDialog.cpp
@@ -0,0 +1,630 @@
+/**
+ * @file RobotDogControlDialog.cpp
+ * @brief 机器狗控制对话框实现
+ * @author Qt UI Optimizer
+ * @date 2024-07-04
+ * @version 1.0
+ */
+
+#include "ui/dialogs/RobotDogControlDialog.h"
+#include "styles/ModernStyleManager.h"
+
+#include
+#include
+#include
+#include
+
+RobotDogControlDialog::RobotDogControlDialog(QWidget *parent)
+ : QDialog(parent)
+ , m_mainLayout(nullptr)
+ , m_contentLayout(nullptr)
+ , m_isMappingActive(false)
+ , m_isNavigationActive(false)
+ , m_isPhotoTransmissionActive(false)
+ , m_isPersonRecognitionActive(false)
+ , m_isMoving(false)
+ , m_currentPosture("站立")
+ , m_statusUpdateTimer(new QTimer(this))
+{
+ setupUI();
+ applyStyles();
+ connectSignals();
+
+ // 启动状态更新定时器
+ m_statusUpdateTimer->start(1000);
+}
+
+RobotDogControlDialog::~RobotDogControlDialog()
+{
+ if (m_statusUpdateTimer) {
+ m_statusUpdateTimer->stop();
+ }
+}
+
+void RobotDogControlDialog::setupUI()
+{
+ setWindowTitle("🐕 机器狗控制中心");
+ setModal(false);
+ setMinimumSize(900, 700);
+ resize(1000, 750);
+
+ // 窗口居中显示
+ QRect screenGeometry = QApplication::desktop()->screenGeometry();
+ int x = (screenGeometry.width() - this->width()) / 2;
+ int y = (screenGeometry.height() - this->height()) / 2;
+ move(x, y);
+
+ m_mainLayout = new QVBoxLayout(this);
+ m_mainLayout->setSpacing(20);
+ m_mainLayout->setContentsMargins(20, 20, 20, 20);
+
+ // 标题
+ QLabel *titleLabel = new QLabel("🐕 机器狗控制中心");
+ titleLabel->setObjectName("DialogTitle");
+ titleLabel->setAlignment(Qt::AlignCenter);
+ titleLabel->setStyleSheet(
+ "font-size: 24px; "
+ "font-weight: bold; "
+ "color: #16a085; "
+ "padding: 10px; "
+ "border-bottom: 2px solid #16a085; "
+ "margin-bottom: 10px;"
+ );
+ m_mainLayout->addWidget(titleLabel);
+
+ // 主内容区域
+ m_contentLayout = new QHBoxLayout();
+ m_contentLayout->setSpacing(20);
+
+ setupMovementControlModule();
+ setupMissionControlModule();
+ setupStatusMonitorModule();
+
+ m_mainLayout->addLayout(m_contentLayout);
+
+ // 底部按钮
+ QHBoxLayout *buttonLayout = new QHBoxLayout();
+ buttonLayout->addStretch();
+
+ QPushButton *closeBtn = new QPushButton("关闭");
+ closeBtn->setObjectName("CloseBtn");
+ closeBtn->setMinimumSize(100, 40);
+ connect(closeBtn, &QPushButton::clicked, this, &QDialog::close);
+
+ buttonLayout->addWidget(closeBtn);
+ m_mainLayout->addLayout(buttonLayout);
+}
+
+void RobotDogControlDialog::setupMovementControlModule()
+{
+ m_movementControlGroup = new QGroupBox("🎮 运动控制");
+ m_movementControlGroup->setObjectName("ControlGroup");
+ m_movementControlGroup->setMinimumWidth(280);
+
+ QVBoxLayout *movementLayout = new QVBoxLayout(m_movementControlGroup);
+ movementLayout->setSpacing(15);
+
+ // 方向控制按钮 - 十字布局
+ QGridLayout *directionLayout = new QGridLayout();
+ directionLayout->setSpacing(10);
+
+ m_forwardBtn = new QPushButton("⬆️ 前进");
+ m_forwardBtn->setObjectName("DirectionBtn");
+ m_forwardBtn->setMinimumHeight(50);
+
+ m_backwardBtn = new QPushButton("⬇️ 后退");
+ m_backwardBtn->setObjectName("DirectionBtn");
+ m_backwardBtn->setMinimumHeight(50);
+
+ m_leftBtn = new QPushButton("⬅️ 左转");
+ m_leftBtn->setObjectName("DirectionBtn");
+ m_leftBtn->setMinimumHeight(50);
+
+ m_rightBtn = new QPushButton("➡️ 右转");
+ m_rightBtn->setObjectName("DirectionBtn");
+ m_rightBtn->setMinimumHeight(50);
+
+ m_stopBtn = new QPushButton("⏹️ 停止");
+ m_stopBtn->setObjectName("StopBtn");
+ m_stopBtn->setMinimumHeight(50);
+
+ // 十字布局
+ directionLayout->addWidget(m_forwardBtn, 0, 1);
+ directionLayout->addWidget(m_leftBtn, 1, 0);
+ directionLayout->addWidget(m_stopBtn, 1, 1);
+ directionLayout->addWidget(m_rightBtn, 1, 2);
+ directionLayout->addWidget(m_backwardBtn, 2, 1);
+
+ movementLayout->addLayout(directionLayout);
+
+ // 姿态控制按钮
+ QLabel *postureLabel = new QLabel("姿态控制:");
+ movementLayout->addWidget(postureLabel);
+
+ QHBoxLayout *postureLayout = new QHBoxLayout();
+ postureLayout->setSpacing(10);
+
+ m_standBtn = new QPushButton("🧍 站立");
+ m_standBtn->setObjectName("PostureBtn");
+ m_standBtn->setMinimumHeight(45);
+
+ m_lieDownBtn = new QPushButton("🛌 趴下");
+ m_lieDownBtn->setObjectName("PostureBtn");
+ m_lieDownBtn->setMinimumHeight(45);
+
+ m_jumpBtn = new QPushButton("🦘 跳跃");
+ m_jumpBtn->setObjectName("PostureBtn");
+ m_jumpBtn->setMinimumHeight(45);
+
+ postureLayout->addWidget(m_standBtn);
+ postureLayout->addWidget(m_lieDownBtn);
+ postureLayout->addWidget(m_jumpBtn);
+ movementLayout->addLayout(postureLayout);
+
+ // 速度控制
+ QLabel *speedLabel = new QLabel("移动速度:");
+ m_speedSlider = new QSlider(Qt::Horizontal);
+ m_speedSlider->setRange(1, 10);
+ m_speedSlider->setValue(5);
+
+ movementLayout->addWidget(speedLabel);
+ movementLayout->addWidget(m_speedSlider);
+
+ // 紧急停止按钮
+ m_emergencyStopBtn = new QPushButton("🚨 紧急停止");
+ m_emergencyStopBtn->setObjectName("DangerBtn");
+ m_emergencyStopBtn->setMinimumHeight(60);
+ m_emergencyStopBtn->setStyleSheet(
+ "QPushButton {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #e74c3c, stop:1 #c0392b);"
+ " color: white;"
+ " font-size: 16px;"
+ " font-weight: bold;"
+ " border: 2px solid #e74c3c;"
+ " border-radius: 8px;"
+ "}"
+ "QPushButton:hover {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #c0392b, stop:1 #a93226);"
+ "}"
+ );
+
+ movementLayout->addWidget(m_emergencyStopBtn);
+ movementLayout->addStretch();
+
+ m_contentLayout->addWidget(m_movementControlGroup);
+}
+
+void RobotDogControlDialog::setupMissionControlModule()
+{
+ m_missionControlGroup = new QGroupBox("🎯 任务控制");
+ m_missionControlGroup->setObjectName("ControlGroup");
+ m_missionControlGroup->setMinimumWidth(280);
+
+ QVBoxLayout *missionLayout = new QVBoxLayout(m_missionControlGroup);
+ missionLayout->setSpacing(15);
+
+ // 任务模式选择
+ QLabel *modeLabel = new QLabel("任务模式:");
+ m_missionModeCombo = new QComboBox();
+ m_missionModeCombo->addItems({"手动控制", "自主巡逻", "目标跟踪", "区域探索", "护卫模式"});
+ m_missionModeCombo->setMinimumHeight(35);
+
+ missionLayout->addWidget(modeLabel);
+ missionLayout->addWidget(m_missionModeCombo);
+
+ // 功能控制按钮
+ m_mappingBtn = new QPushButton("🗺️ 开始建图");
+ m_mappingBtn->setObjectName("FunctionBtn");
+ m_mappingBtn->setMinimumHeight(50);
+ m_mappingBtn->setCheckable(true);
+
+ m_navigationBtn = new QPushButton("🧭 导航避障");
+ m_navigationBtn->setObjectName("FunctionBtn");
+ m_navigationBtn->setMinimumHeight(50);
+ m_navigationBtn->setCheckable(true);
+
+ m_photoBtn = new QPushButton("📸 照片传输");
+ m_photoBtn->setObjectName("FunctionBtn");
+ m_photoBtn->setMinimumHeight(50);
+ m_photoBtn->setCheckable(true);
+
+ m_recognitionBtn = new QPushButton("👁️ 人物识别");
+ m_recognitionBtn->setObjectName("FunctionBtn");
+ m_recognitionBtn->setMinimumHeight(50);
+ m_recognitionBtn->setCheckable(true);
+
+ missionLayout->addWidget(m_mappingBtn);
+ missionLayout->addWidget(m_navigationBtn);
+ missionLayout->addWidget(m_photoBtn);
+ missionLayout->addWidget(m_recognitionBtn);
+ missionLayout->addStretch();
+
+ m_contentLayout->addWidget(m_missionControlGroup);
+}
+
+void RobotDogControlDialog::setupStatusMonitorModule()
+{
+ m_statusGroup = new QGroupBox("📊 状态监控");
+ m_statusGroup->setObjectName("ControlGroup");
+ m_statusGroup->setMinimumWidth(320);
+
+ QVBoxLayout *statusLayout = new QVBoxLayout(m_statusGroup);
+ statusLayout->setSpacing(15);
+
+ // 电池状态
+ QHBoxLayout *batteryLayout = new QHBoxLayout();
+ m_batteryLabel = new QLabel("电池电量:");
+ m_batteryProgress = new QProgressBar();
+ m_batteryProgress->setRange(0, 100);
+ m_batteryProgress->setValue(90);
+ m_batteryProgress->setTextVisible(true);
+ m_batteryProgress->setFormat("%p%");
+
+ batteryLayout->addWidget(m_batteryLabel);
+ batteryLayout->addWidget(m_batteryProgress);
+ statusLayout->addLayout(batteryLayout);
+
+ // 运行参数
+ QGridLayout *paramLayout = new QGridLayout();
+ paramLayout->addWidget(new QLabel("移动速度:"), 0, 0);
+ m_speedLabel = new QLabel("0.0 m/s");
+ m_speedLabel->setStyleSheet("font-weight: bold; color: #16a085;");
+ paramLayout->addWidget(m_speedLabel, 0, 1);
+
+ paramLayout->addWidget(new QLabel("设备温度:"), 1, 0);
+ m_temperatureLabel = new QLabel("35.2°C");
+ m_temperatureLabel->setStyleSheet("font-weight: bold; color: #16a085;");
+ paramLayout->addWidget(m_temperatureLabel, 1, 1);
+
+ paramLayout->addWidget(new QLabel("当前姿态:"), 2, 0);
+ m_postureLabel = new QLabel("🧍 站立");
+ paramLayout->addWidget(m_postureLabel, 2, 1);
+
+ paramLayout->addWidget(new QLabel("连接状态:"), 3, 0);
+ m_connectionLabel = new QLabel("🟢 已连接");
+ paramLayout->addWidget(m_connectionLabel, 3, 1);
+
+ statusLayout->addLayout(paramLayout);
+
+ // 日志显示
+ QLabel *logLabel = new QLabel("系统日志:");
+ m_logTextEdit = new QTextEdit();
+ m_logTextEdit->setMaximumHeight(200);
+ m_logTextEdit->setReadOnly(true);
+ m_logTextEdit->append(QString("[%1] 机器狗控制系统启动").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ m_logTextEdit->append(QString("[%1] 机器狗已连接,当前状态:待命").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+
+ statusLayout->addWidget(logLabel);
+ statusLayout->addWidget(m_logTextEdit);
+
+ m_contentLayout->addWidget(m_statusGroup);
+}
+
+void RobotDogControlDialog::applyStyles()
+{
+ // 应用现代样式管理器
+ ModernStyleManager* styleManager = ModernStyleManager::getInstance();
+
+ // 设置对话框样式
+ setStyleSheet(
+ "QDialog {"
+ " background-color: #f8f9fa;"
+ " border: 1px solid #dee2e6;"
+ "}"
+ "QGroupBox {"
+ " font-size: 16px;"
+ " font-weight: bold;"
+ " color: #495057;"
+ " border: 2px solid #dee2e6;"
+ " border-radius: 8px;"
+ " margin-top: 10px;"
+ " padding-top: 10px;"
+ "}"
+ "QGroupBox::title {"
+ " subcontrol-origin: margin;"
+ " left: 10px;"
+ " padding: 0 8px 0 8px;"
+ " background-color: #f8f9fa;"
+ "}"
+ "QPushButton#DirectionBtn {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #16a085, stop:1 #138d75);"
+ " color: white;"
+ " font-size: 14px;"
+ " font-weight: bold;"
+ " border: 2px solid #16a085;"
+ " border-radius: 8px;"
+ " padding: 8px;"
+ "}"
+ "QPushButton#DirectionBtn:hover {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #138d75, stop:1 #117a65);"
+ "}"
+ "QPushButton#DirectionBtn:pressed {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #117a65, stop:1 #0e6b5d);"
+ "}"
+ "QPushButton#StopBtn {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #e67e22, stop:1 #d35400);"
+ " color: white;"
+ " font-size: 14px;"
+ " font-weight: bold;"
+ " border: 2px solid #e67e22;"
+ " border-radius: 8px;"
+ " padding: 8px;"
+ "}"
+ "QPushButton#PostureBtn {"
+ " background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
+ " stop:0 #3498db, stop:1 #2980b9);"
+ " color: white;"
+ " font-size: 13px;"
+ " font-weight: bold;"
+ " border: 2px solid #3498db;"
+ " border-radius: 6px;"
+ " padding: 6px;"
+ "}"
+ "QSlider::groove:horizontal {"
+ " border: 1px solid #bbb;"
+ " background: white;"
+ " height: 10px;"
+ " border-radius: 4px;"
+ "}"
+ "QSlider::handle:horizontal {"
+ " background: #16a085;"
+ " border: 1px solid #5c5c5c;"
+ " width: 18px;"
+ " margin: -2px 0;"
+ " border-radius: 3px;"
+ "}"
+ "QProgressBar {"
+ " border: 2px solid #dee2e6;"
+ " border-radius: 5px;"
+ " text-align: center;"
+ " font-weight: bold;"
+ "}"
+ "QProgressBar::chunk {"
+ " background-color: #28a745;"
+ " border-radius: 3px;"
+ "}"
+ "QTextEdit {"
+ " border: 1px solid #dee2e6;"
+ " border-radius: 4px;"
+ " background-color: white;"
+ " font-family: 'Consolas', monospace;"
+ " font-size: 12px;"
+ "}"
+ );
+}
+
+void RobotDogControlDialog::connectSignals()
+{
+ // 运动控制信号连接
+ connect(m_forwardBtn, &QPushButton::clicked, this, &RobotDogControlDialog::onMoveForwardClicked);
+ connect(m_backwardBtn, &QPushButton::clicked, this, &RobotDogControlDialog::onMoveBackwardClicked);
+ connect(m_leftBtn, &QPushButton::clicked, this, &RobotDogControlDialog::onTurnLeftClicked);
+ connect(m_rightBtn, &QPushButton::clicked, this, &RobotDogControlDialog::onTurnRightClicked);
+ connect(m_stopBtn, &QPushButton::clicked, this, &RobotDogControlDialog::onStopClicked);
+
+ // 姿态控制信号连接
+ connect(m_standBtn, &QPushButton::clicked, this, &RobotDogControlDialog::onStandClicked);
+ connect(m_lieDownBtn, &QPushButton::clicked, this, &RobotDogControlDialog::onLieDownClicked);
+ connect(m_jumpBtn, &QPushButton::clicked, this, &RobotDogControlDialog::onJumpClicked);
+
+ // 紧急停止
+ connect(m_emergencyStopBtn, &QPushButton::clicked, this, &RobotDogControlDialog::onEmergencyStop);
+
+ // 任务控制信号连接
+ connect(m_mappingBtn, &QPushButton::clicked, this, &RobotDogControlDialog::onMappingToggle);
+ connect(m_navigationBtn, &QPushButton::clicked, this, &RobotDogControlDialog::onNavigationToggle);
+ connect(m_photoBtn, &QPushButton::clicked, this, &RobotDogControlDialog::onPhotoTransmissionToggle);
+ connect(m_recognitionBtn, &QPushButton::clicked, this, &RobotDogControlDialog::onPersonRecognitionToggle);
+
+ // 速度滑块
+ connect(m_speedSlider, &QSlider::valueChanged, [this](int value) {
+ m_logTextEdit->append(QString("[%1] 速度设置为: %2").arg(
+ QDateTime::currentDateTime().toString("hh:mm:ss")).arg(value));
+ });
+
+ // 状态更新定时器
+ connect(m_statusUpdateTimer, &QTimer::timeout, [this]() {
+ // 模拟状态更新
+ static int counter = 0;
+ counter++;
+
+ if (m_isMoving) {
+ // 模拟电池消耗
+ int currentBattery = m_batteryProgress->value();
+ if (currentBattery > 0 && counter % 15 == 0) {
+ m_batteryProgress->setValue(currentBattery - 1);
+ }
+
+ // 更新电池颜色
+ if (currentBattery > 50) {
+ m_batteryProgress->setStyleSheet("QProgressBar::chunk { background-color: #28a745; }");
+ } else if (currentBattery > 20) {
+ m_batteryProgress->setStyleSheet("QProgressBar::chunk { background-color: #ffc107; }");
+ } else {
+ m_batteryProgress->setStyleSheet("QProgressBar::chunk { background-color: #dc3545; }");
+ }
+
+ // 模拟温度变化
+ static double temperature = 35.2;
+ temperature += (qrand() % 21 - 10) * 0.1; // ±1度随机变化
+ if (temperature < 30.0) temperature = 30.0;
+ if (temperature > 45.0) temperature = 45.0;
+ m_temperatureLabel->setText(QString("%1°C").arg(temperature, 0, 'f', 1));
+
+ // 温度颜色警告
+ if (temperature > 40.0) {
+ m_temperatureLabel->setStyleSheet("font-weight: bold; color: #dc3545;");
+ } else if (temperature > 38.0) {
+ m_temperatureLabel->setStyleSheet("font-weight: bold; color: #ffc107;");
+ } else {
+ m_temperatureLabel->setStyleSheet("font-weight: bold; color: #16a085;");
+ }
+ }
+ });
+}
+
+// 运动控制槽函数实现
+void RobotDogControlDialog::onMoveForwardClicked()
+{
+ m_isMoving = true;
+ m_logTextEdit->append(QString("[%1] 机器狗开始前进").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ updateRobotStatus(m_batteryProgress->value(), m_speedSlider->value() * 0.5, 35.5);
+}
+
+void RobotDogControlDialog::onMoveBackwardClicked()
+{
+ m_isMoving = true;
+ m_logTextEdit->append(QString("[%1] 机器狗开始后退").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ updateRobotStatus(m_batteryProgress->value(), m_speedSlider->value() * 0.3, 35.3);
+}
+
+void RobotDogControlDialog::onTurnLeftClicked()
+{
+ m_isMoving = true;
+ m_logTextEdit->append(QString("[%1] 机器狗开始左转").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ updateRobotStatus(m_batteryProgress->value(), m_speedSlider->value() * 0.2, 35.1);
+}
+
+void RobotDogControlDialog::onTurnRightClicked()
+{
+ m_isMoving = true;
+ m_logTextEdit->append(QString("[%1] 机器狗开始右转").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ updateRobotStatus(m_batteryProgress->value(), m_speedSlider->value() * 0.2, 35.1);
+}
+
+void RobotDogControlDialog::onStopClicked()
+{
+ m_isMoving = false;
+ m_logTextEdit->append(QString("[%1] 机器狗停止移动").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ updateRobotStatus(m_batteryProgress->value(), 0.0, 34.8);
+}
+
+void RobotDogControlDialog::onStandClicked()
+{
+ m_currentPosture = "站立";
+ m_postureLabel->setText("🧍 站立");
+ m_logTextEdit->append(QString("[%1] 机器狗切换到站立姿态").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+}
+
+void RobotDogControlDialog::onLieDownClicked()
+{
+ m_currentPosture = "趴下";
+ m_postureLabel->setText("🛌 趴下");
+ m_logTextEdit->append(QString("[%1] 机器狗切换到趴下姿态").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+
+ // 趴下时停止移动
+ if (m_isMoving) {
+ onStopClicked();
+ }
+}
+
+void RobotDogControlDialog::onJumpClicked()
+{
+ m_logTextEdit->append(QString("[%1] 机器狗执行跳跃动作").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+
+ // 跳跃后恢复站立姿态
+ QTimer::singleShot(1000, [this]() {
+ onStandClicked();
+ m_logTextEdit->append(QString("[%1] 跳跃动作完成").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ });
+}
+
+void RobotDogControlDialog::onEmergencyStop()
+{
+ QMessageBox::StandardButton reply = QMessageBox::warning(this, "紧急停止",
+ "确定要执行紧急停止吗?这将立即停止所有操作!",
+ QMessageBox::Yes | QMessageBox::No);
+
+ if (reply == QMessageBox::Yes) {
+ m_logTextEdit->append(QString("[%1] 🚨 执行紧急停止!").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ onStopClicked();
+
+ // 停止所有任务
+ if (m_isMappingActive) onMappingToggle();
+ if (m_isNavigationActive) onNavigationToggle();
+ if (m_isPhotoTransmissionActive) onPhotoTransmissionToggle();
+ if (m_isPersonRecognitionActive) onPersonRecognitionToggle();
+ }
+}
+
+// 任务控制槽函数实现
+void RobotDogControlDialog::onMappingToggle()
+{
+ m_isMappingActive = !m_isMappingActive;
+
+ if (m_isMappingActive) {
+ m_mappingBtn->setText("🗺️ 停止建图");
+ m_mappingBtn->setStyleSheet("background-color: #dc3545; color: white;");
+ m_logTextEdit->append(QString("[%1] 开始自主建图").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit startMapping();
+ } else {
+ m_mappingBtn->setText("🗺️ 开始建图");
+ m_mappingBtn->setStyleSheet("");
+ m_logTextEdit->append(QString("[%1] 停止自主建图").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit stopMapping();
+ }
+}
+
+void RobotDogControlDialog::onNavigationToggle()
+{
+ m_isNavigationActive = !m_isNavigationActive;
+
+ if (m_isNavigationActive) {
+ m_navigationBtn->setText("🧭 停止导航");
+ m_navigationBtn->setStyleSheet("background-color: #dc3545; color: white;");
+ m_logTextEdit->append(QString("[%1] 开始导航避障").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit startNavigation();
+ } else {
+ m_navigationBtn->setText("🧭 导航避障");
+ m_navigationBtn->setStyleSheet("");
+ m_logTextEdit->append(QString("[%1] 停止导航避障").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit stopNavigation();
+ }
+}
+
+void RobotDogControlDialog::onPhotoTransmissionToggle()
+{
+ m_isPhotoTransmissionActive = !m_isPhotoTransmissionActive;
+
+ if (m_isPhotoTransmissionActive) {
+ m_photoBtn->setText("📸 停止传输");
+ m_photoBtn->setStyleSheet("background-color: #dc3545; color: white;");
+ m_logTextEdit->append(QString("[%1] 开始照片传输").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit startPhotoTransmission();
+ } else {
+ m_photoBtn->setText("📸 照片传输");
+ m_photoBtn->setStyleSheet("");
+ m_logTextEdit->append(QString("[%1] 停止照片传输").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit stopPhotoTransmission();
+ }
+}
+
+void RobotDogControlDialog::onPersonRecognitionToggle()
+{
+ m_isPersonRecognitionActive = !m_isPersonRecognitionActive;
+
+ if (m_isPersonRecognitionActive) {
+ m_recognitionBtn->setText("👁️ 停止识别");
+ m_recognitionBtn->setStyleSheet("background-color: #dc3545; color: white;");
+ m_logTextEdit->append(QString("[%1] 开始人物识别").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit startPersonRecognition();
+ } else {
+ m_recognitionBtn->setText("👁️ 人物识别");
+ m_recognitionBtn->setStyleSheet("");
+ m_logTextEdit->append(QString("[%1] 停止人物识别").arg(QDateTime::currentDateTime().toString("hh:mm:ss")));
+ emit stopPersonRecognition();
+ }
+}
+
+void RobotDogControlDialog::updateRobotStatus(int battery, double speed, double temperature)
+{
+ m_batteryProgress->setValue(battery);
+ m_speedLabel->setText(QString("%1 m/s").arg(speed, 0, 'f', 1));
+ m_temperatureLabel->setText(QString("%1°C").arg(temperature, 0, 'f', 1));
+}
diff --git a/src/Client/src/ui/main/MainWindow.cpp b/src/Client/src/ui/main/MainWindow.cpp
index cb132824..4c306f0b 100644
--- a/src/Client/src/ui/main/MainWindow.cpp
+++ b/src/Client/src/ui/main/MainWindow.cpp
@@ -55,6 +55,9 @@ MainWindow::MainWindow(QWidget *parent)
, m_rightFunctionPanel(nullptr)
, m_leftPanelSplitter(nullptr)
, m_intelligenceUI(nullptr)
+ , m_faceLightControl(nullptr)
+ // , m_droneControlDialog(nullptr)
+ // , m_robotDogControlDialog(nullptr)
{
m_ui->setupUi(this);
@@ -64,7 +67,7 @@ MainWindow::MainWindow(QWidget *parent)
// 初始化现代样式管理器
initializeModernStyles();
-
+
// 初始化默认数据
m_robotList.append(qMakePair(QString("Alice"), QString("192.168.0.1")));
m_robotList.append(qMakePair(QString("Bob"), QString("192.168.0.2")));
@@ -76,6 +79,18 @@ MainWindow::~MainWindow()
delete m_intelligenceUI;
m_intelligenceUI = nullptr;
}
+ if (m_faceLightControl) {
+ delete m_faceLightControl;
+ m_faceLightControl = nullptr;
+ }
+ // if (m_droneControlDialog) {
+ // delete m_droneControlDialog;
+ // m_droneControlDialog = nullptr;
+ // }
+ // if (m_robotDogControlDialog) {
+ // delete m_robotDogControlDialog;
+ // m_robotDogControlDialog = nullptr;
+ // }
delete m_ui;
}
@@ -83,31 +98,35 @@ void MainWindow::setupUI()
{
// 设置窗口最小尺寸
this->setMinimumSize(1400, 1000);
-
+
// 窗口接近全屏显示
QRect screenGeometry = QApplication::desktop()->screenGeometry();
int width = screenGeometry.width() - 100; // 留50px边距
int height = screenGeometry.height() - 100; // 留50px边距
this->resize(width, height);
-
+
// 窗口居中显示
int x = (screenGeometry.width() - this->width()) / 2;
int y = (screenGeometry.height() - this->height()) / 2;
this->move(x, y);
-
+
// 初始化随机数生成器
qsrand(QTime::currentTime().msec());
-
+
// 创建并集成SystemLogPanel和DeviceListPanel到左侧面板
setupSystemLogPanel();
-
+
// 创建并集成右侧功能面板
setupRightFunctionPanel();
-
+
// 恢复地图显示控制
setupMapDisplay();
+
+ // 修复主要功能按钮布局问题
+ fixMainButtonLayout();
+
// 注意:原有的重复设备管理按钮已被移除,功能集成在DeviceListPanel中
-
+
// 记录系统启动日志
SystemLogger::getInstance()->logInfo("系统启动完成");
}
@@ -210,27 +229,35 @@ void MainWindow::setupRightFunctionPanel()
rightLayout->addWidget(m_rightFunctionPanel);
// 连接右侧功能面板信号
- // 战场探索模块信号
- connect(m_rightFunctionPanel, &RightFunctionPanel::startMapping,
+ // 战场探索模块控制信号
+ connect(m_rightFunctionPanel, &RightFunctionPanel::droneControlRequested,
+ this, &MainWindow::onDroneControlRequested);
+ connect(m_rightFunctionPanel, &RightFunctionPanel::robotDogControlRequested,
+ this, &MainWindow::onRobotDogControlRequested);
+
+ // 战场探索模块功能信号
+ connect(m_rightFunctionPanel, &RightFunctionPanel::startMapping,
this, &MainWindow::onStartMapping);
- connect(m_rightFunctionPanel, &RightFunctionPanel::stopMapping,
+ connect(m_rightFunctionPanel, &RightFunctionPanel::stopMapping,
this, &MainWindow::onStopMapping);
- connect(m_rightFunctionPanel, &RightFunctionPanel::startNavigation,
+ connect(m_rightFunctionPanel, &RightFunctionPanel::startNavigation,
this, &MainWindow::onStartNavigation);
- connect(m_rightFunctionPanel, &RightFunctionPanel::stopNavigation,
+ connect(m_rightFunctionPanel, &RightFunctionPanel::stopNavigation,
this, &MainWindow::onStopNavigation);
- connect(m_rightFunctionPanel, &RightFunctionPanel::startPhotoTransmission,
+ connect(m_rightFunctionPanel, &RightFunctionPanel::startPhotoTransmission,
this, &MainWindow::onStartPhotoTransmission);
- connect(m_rightFunctionPanel, &RightFunctionPanel::stopPhotoTransmission,
+ connect(m_rightFunctionPanel, &RightFunctionPanel::stopPhotoTransmission,
this, &MainWindow::onStopPhotoTransmission);
- connect(m_rightFunctionPanel, &RightFunctionPanel::startPersonRecognition,
+ connect(m_rightFunctionPanel, &RightFunctionPanel::startPersonRecognition,
this, &MainWindow::onStartPersonRecognition);
- connect(m_rightFunctionPanel, &RightFunctionPanel::stopPersonRecognition,
+ connect(m_rightFunctionPanel, &RightFunctionPanel::stopPersonRecognition,
this, &MainWindow::onStopPersonRecognition);
// 情报传输模块信号
connect(m_rightFunctionPanel, &RightFunctionPanel::openIntelligenceUI,
this, &MainWindow::onIntelligenceClicked);
+ connect(m_rightFunctionPanel, &RightFunctionPanel::openFaceLightUI,
+ this, &MainWindow::onFaceLightClicked);
// 敌情统计模块信号
connect(m_rightFunctionPanel, &RightFunctionPanel::refreshEnemyStats,
@@ -264,115 +291,11 @@ void MainWindow::setupDeviceListPanel()
void MainWindow::setupStyle()
{
- // 注意:样式设置已迁移到ModernStyleManager
// 在initializeModernStyles()方法中统一管理
-
- // 设置菜单栏样式 - 与整体界面保持一致
- setupMenuBarStyle();
-
- // 设置状态栏样式 - 与整体界面保持一致
- setupStatusBarStyle();
-
+
SystemLogger::getInstance()->logInfo("基础样式设置完成,现代样式将在initializeModernStyles()中应用");
}
-void MainWindow::setupMenuBarStyle()
-{
- // 设置菜单栏样式,与整体界面保持一致的军用风格
- QString menuBarStyle =
- "QMenuBar {"
- " background: qlineargradient(x1:0, y1:0, x2:1, y2:1, "
- " stop:0 rgba(20, 30, 42, 0.98), "
- " stop:1 rgba(35, 50, 65, 0.98));"
- " color: rgb(240, 248, 255);"
- " border-bottom: 3px solid rgba(82, 194, 242, 0.8);"
- " font-size: 20px;"
- " font-weight: bold;"
- " font-family: 'Microsoft YaHei', 'SimHei', sans-serif;"
- " padding: 15px 25px;"
- " min-height: 50px;"
- " height: 50px;"
- "}"
- "QMenuBar::item {"
- " background: transparent;"
- " color: rgb(240, 248, 255);"
- " padding: 15px 25px;"
- " margin: 4px 8px;"
- " border-radius: 10px;"
- " font-size: 20px;"
- " font-weight: bold;"
- " min-width: 100px;"
- " text-align: center;"
- "}"
- "QMenuBar::item:selected {"
- " background: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
- " stop:0 rgba(82, 194, 242, 0.6), "
- " stop:1 rgba(45, 120, 180, 0.6));"
- " border: 1px solid rgba(82, 194, 242, 0.8);"
- " color: white;"
- "}"
- "QMenuBar::item:pressed {"
- " background: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
- " stop:0 rgba(82, 194, 242, 0.8), "
- " stop:1 rgba(45, 120, 180, 0.8));"
- " border: 1px solid rgba(82, 194, 242, 1.0);"
- "}"
- "QMenu {"
- " background: qlineargradient(x1:0, y1:0, x2:1, y2:1, "
- " stop:0 rgba(25, 35, 45, 0.95), "
- " stop:1 rgba(35, 50, 65, 0.95));"
- " color: rgb(220, 230, 242);"
- " border: 2px solid rgba(82, 194, 242, 0.6);"
- " border-radius: 8px;"
- " font-size: 14px;"
- " font-weight: 500;"
- " padding: 8px;"
- "}"
- "QMenu::item {"
- " background: transparent;"
- " padding: 8px 16px;"
- " margin: 2px;"
- " border-radius: 4px;"
- " min-width: 120px;"
- "}"
- "QMenu::item:selected {"
- " background: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
- " stop:0 rgba(82, 194, 242, 0.6), "
- " stop:1 rgba(45, 120, 180, 0.6));"
- " border: 1px solid rgba(82, 194, 242, 0.8);"
- " color: white;"
- "}";
-
- m_ui->menubar->setStyleSheet(menuBarStyle);
-}
-
-void MainWindow::setupStatusBarStyle()
-{
- // 设置状态栏样式,与整体界面保持一致的军用风格
- QString statusBarStyle =
- "QStatusBar {"
- " background: qlineargradient(x1:0, y1:0, x2:1, y2:1, "
- " stop:0 rgba(15, 22, 32, 0.95), "
- " stop:1 rgba(25, 35, 45, 0.95));"
- " color: rgb(180, 200, 220);"
- " border-top: 2px solid rgba(82, 194, 242, 0.6);"
- " font-size: 14px;"
- " font-weight: 500;"
- " font-family: 'Microsoft YaHei', 'SimHei', sans-serif;"
- " padding: 6px 16px;"
- " min-height: 25px;"
- "}"
- "QStatusBar::item {"
- " border: none;"
- " background: transparent;"
- "}";
-
- m_ui->statusbar->setStyleSheet(statusBarStyle);
-
- // 设置状态栏默认消息
- m_ui->statusbar->showMessage("战场探索系统 - 就绪状态", 0);
-}
-
void MainWindow::connectSignals()
{
// 连接按钮信号
@@ -886,6 +809,16 @@ void MainWindow::onIntelligenceClicked()
m_intelligenceUI->raise();
}
+void MainWindow::onFaceLightClicked()
+{
+ if (!m_faceLightControl) {
+ m_faceLightControl = new FaceLightControl(this);
+ }
+ m_faceLightControl->show();
+ m_faceLightControl->activateWindow();
+ m_faceLightControl->raise();
+}
+
void MainWindow::onDeviceSelected(const QString &deviceId)
{
qDebug() << "Device selected:" << deviceId;
@@ -1136,8 +1069,10 @@ void MainWindow::initializeDeviceMarkersOnMap()
.arg(device.longitude)
.arg(device.status);
- webView->page()->runJavaScript(jsCode, [device](const QVariant &result) {
- qDebug() << "Device marker added for:" << device.name;
+ // 复制设备名称避免访问已销毁的对象
+ QString deviceName = device.name;
+ webView->page()->runJavaScript(jsCode, [deviceName](const QVariant &result) {
+ qDebug() << "Device marker added for:" << deviceName;
});
}
@@ -1324,6 +1259,51 @@ void MainWindow::onExportReport()
QString("战场报告已成功导出到:\n%1").arg(reportPath));
}
+void MainWindow::fixMainButtonLayout()
+{
+ // 修复主要功能按钮的布局问题
+ if (!m_ui->UAVview || !m_ui->robotView || !m_ui->robotMapping || !m_ui->smartNavigation) {
+ qWarning() << "某些主要功能按钮未找到,跳过布局修复";
+ return;
+ }
+
+ // 设置按钮属性的通用函数
+ auto setupButton = [](QPushButton* button, const QString& text, const QString& tooltip, int fontSize = 12) {
+ if (!button) return;
+
+ // 设置尺寸
+ button->setMinimumSize(140, 45);
+ button->setMaximumHeight(45);
+ button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+
+ // 设置文本和提示
+ button->setText(text);
+ button->setToolTip(tooltip);
+
+ // 设置字体
+ QFont font = button->font();
+ font.setPointSize(fontSize);
+ font.setBold(true);
+ button->setFont(font);
+ };
+
+ // 设置四个主要按钮的属性
+ setupButton(m_ui->UAVview, "🚁 无人机视角", "查看无人机实时视频流和飞行状态");
+ setupButton(m_ui->robotView, "🐕 机器狗视角", "查看机器狗实时视频流和运动状态");
+ setupButton(m_ui->robotMapping, "🗺️ 机器狗建图", "启动机器狗SLAM建图功能");
+ setupButton(m_ui->smartNavigation, "🧭 智能导航", "启动智能路径规划和自主导航");
+
+ // 设置情报传达按钮
+ if (m_ui->intelligence) {
+ setupButton(m_ui->intelligence, "🔊 情报传达", "语音情报传达和通信功能", 11);
+ m_ui->intelligence->setMinimumHeight(40);
+ m_ui->intelligence->setMaximumHeight(40);
+ }
+
+ qDebug() << "主要功能按钮布局修复完成";
+ SystemLogger::getInstance()->logInfo("主要功能按钮布局修复完成");
+}
+
void MainWindow::initializeModernStyles()
{
// 获取现代样式管理器实例
@@ -1369,4 +1349,36 @@ void MainWindow::initializeModernStyles()
});
SystemLogger::getInstance()->logInfo("现代样式管理器初始化完成");
-}
\ No newline at end of file
+}
+
+// 战场探索模块控制槽函数实现
+void MainWindow::onDroneControlRequested()
+{
+ SystemLogger::getInstance()->logInfo("无人机控制请求");
+
+ // 暂时使用简单的消息框来测试功能
+ QMessageBox::information(this, "无人机控制",
+ "无人机控制界面功能正在开发中...\n"
+ "将包含以下功能:\n"
+ "• 飞行控制(起飞、降落、悬停)\n"
+ "• 航线规划和导航\n"
+ "• 实时视频传输\n"
+ "• 照片拍摄和传输\n"
+ "• 人物识别功能");
+}
+
+void MainWindow::onRobotDogControlRequested()
+{
+ SystemLogger::getInstance()->logInfo("机器狗控制请求");
+
+ // 暂时使用简单的消息框来测试功能
+ QMessageBox::information(this, "机器狗控制",
+ "机器狗控制界面功能正在开发中...\n"
+ "将包含以下功能:\n"
+ "• 运动控制(前进、后退、转向)\n"
+ "• 姿态控制(站立、趴下、跳跃)\n"
+ "• 地图建构和导航\n"
+ "• 视觉识别和跟踪\n"
+ "• 设备状态监控");
+}
+
diff --git a/src/Client/src/utils/ConfigManager.cpp b/src/Client/src/utils/ConfigManager.cpp
index d4f1f05d..7ff79846 100644
--- a/src/Client/src/utils/ConfigManager.cpp
+++ b/src/Client/src/utils/ConfigManager.cpp
@@ -159,9 +159,26 @@ QString ConfigManager::getDatabaseUser() const
QString ConfigManager::getDatabasePassword() const
{
- // 直接返回项目固定密码,便于团队协作和项目交接
- qDebug() << "Using hardcoded database password for project handover";
- return QString("hzk200407140238");
+ // 优先使用环境变量,然后是配置文件,最后是默认值
+ // Priority: Environment variable > Configuration file > Default value
+
+ // 1. 检查环境变量
+ QString envPassword = qgetenv("BES_DB_PASSWORD");
+ if (!envPassword.isEmpty()) {
+ qDebug() << "Using database password from environment variable";
+ return envPassword;
+ }
+
+ // 2. 从配置文件读取
+ QString configPassword = getValue(KEY_DB_PASSWORD, "");
+ if (!configPassword.isEmpty()) {
+ qDebug() << "Using database password from configuration file";
+ return decryptString(configPassword);
+ }
+
+ // 3. 使用默认值(仅用于向后兼容)
+ qDebug() << "Using default database password (consider setting BES_DB_PASSWORD environment variable)";
+ return QString("your_password_here");
}
void ConfigManager::setDatabaseConfig(const QString& host, int port, const QString& database,
diff --git a/src/Client/styles/USAGE_GUIDE.md b/src/Client/styles/USAGE_GUIDE.md
index 47fd39a3..81a329e0 100644
--- a/src/Client/styles/USAGE_GUIDE.md
+++ b/src/Client/styles/USAGE_GUIDE.md
@@ -1,3 +1,4 @@
+
# 样式管理系统使用指南
## 🚀 快速开始
diff --git a/src/Client/styles/left_panel_styles.qss b/src/Client/styles/left_panel_styles.qss
index b65a58aa..ebe37777 100644
--- a/src/Client/styles/left_panel_styles.qss
+++ b/src/Client/styles/left_panel_styles.qss
@@ -52,11 +52,13 @@ DeviceListPanel QPushButton[objectName="addDogButton"] {
border: 2px solid #1e8449;
border-radius: 8px;
color: #ffffff;
- font-size: 13px;
+ font-size: 12px;
font-weight: bold;
- padding: 8px 12px;
- min-height: 36px;
+ padding: 6px 10px;
+ min-height: 40px;
+ max-height: 40px;
min-width: 100px;
+ max-width: 120px;
}
DeviceListPanel QPushButton[objectName="addUAVButton"]:hover,
@@ -83,11 +85,13 @@ DeviceListPanel QPushButton[objectName="deleteDeviceButton"] {
border: 2px solid #a93226;
border-radius: 8px;
color: #ffffff;
- font-size: 13px;
+ font-size: 12px;
font-weight: bold;
- padding: 8px 12px;
- min-height: 36px;
+ padding: 6px 10px;
+ min-height: 40px;
+ max-height: 40px;
min-width: 80px;
+ max-width: 100px;
}
DeviceListPanel QPushButton[objectName="deleteDeviceButton"]:hover {
@@ -118,11 +122,13 @@ DeviceListPanel QPushButton[objectName="refreshButton"] {
border: 2px solid #1e3a5f;
border-radius: 8px;
color: #ffffff;
- font-size: 16px;
+ font-size: 12px;
font-weight: bold;
- padding: 8px;
- min-height: 36px;
- min-width: 40px;
+ padding: 6px 10px;
+ min-height: 40px;
+ max-height: 40px;
+ min-width: 80px;
+ max-width: 100px;
}
DeviceListPanel QPushButton[objectName="refreshButton"]:hover {