123 1 week ago
commit c064453fdb

@ -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)

@ -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()函数才能生效(程序已自动处理)

@ -0,0 +1,210 @@
#include "FaceLightClient.h"
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <sstream>
#include <unistd.h>
void printUsage(const char* programName) {
std::cout << "Usage: " << programName << " [OPTIONS]\n";
std::cout << "\nOptions:\n";
std::cout << " -m, --mode MODE Control mode: all|single|cycle|custom|pattern\n";
std::cout << " -c, --color COLOR Color: red|green|blue|yellow|white|black\n";
std::cout << " -i, --index INDEX LED index (0-11) for single mode\n";
std::cout << " -d, --delay DELAY Delay in milliseconds (default: 2000)\n";
std::cout << " -p, --pattern PATTERN Custom pattern: \"0:red,1:green,2:blue\"\n";
std::cout << " -t, --times TIMES Number of cycles for cycle mode (default: infinite)\n";
std::cout << " -h, --help Show this help message\n";
std::cout << "\nExamples:\n";
std::cout << " " << programName << " -m all -c red # All LEDs red\n";
std::cout << " " << programName << " -m single -i 0 -c blue # LED 0 blue\n";
std::cout << " " << programName << " -m cycle -d 1000 -t 5 # Color cycle 5 times\n";
std::cout << " " << programName << " -m pattern -p \"0:red,5:green\" # Custom pattern\n";
}
std::map<std::string, const uint8_t*> getColorMap(FaceLightClient& client) {
std::map<std::string, const uint8_t*> colors;
colors["red"] = client.red;
colors["green"] = client.green;
colors["blue"] = client.blue;
colors["yellow"] = client.yellow;
colors["white"] = client.white;
colors["black"] = client.black;
return colors;
}
bool parsePattern(const std::string& pattern, std::vector<std::pair<int, std::string>>& ledPattern) {
std::stringstream ss(pattern);
std::string token;
while (std::getline(ss, token, ',')) {
size_t colonPos = token.find(':');
if (colonPos == std::string::npos) {
std::cerr << "Error: Invalid pattern format. Use INDEX:COLOR\n";
return false;
}
try {
int index = std::stoi(token.substr(0, colonPos));
std::string color = token.substr(colonPos + 1);
if (index < 0 || index > 11) {
std::cerr << "Error: LED index must be 0-11\n";
return false;
}
ledPattern.push_back({index, color});
} catch (const std::exception& e) {
std::cerr << "Error: Invalid pattern format\n";
return false;
}
}
return true;
}
int main(int argc, char* argv[]) {
FaceLightClient client;
auto colors = getColorMap(client);
// 默认参数
std::string mode = "all";
std::string color = "red";
int ledIndex = 0;
int delay = 2000;
std::string pattern = "";
int cycles = -1; // -1 表示无限循环
// 解析命令行参数
for (int i = 1; i < argc; i++) {
std::string arg = argv[i];
if (arg == "-h" || arg == "--help") {
printUsage(argv[0]);
return 0;
} else if ((arg == "-m" || arg == "--mode") && i + 1 < argc) {
mode = argv[++i];
} else if ((arg == "-c" || arg == "--color") && i + 1 < argc) {
color = argv[++i];
} else if ((arg == "-i" || arg == "--index") && i + 1 < argc) {
ledIndex = std::atoi(argv[++i]);
} else if ((arg == "-d" || arg == "--delay") && i + 1 < argc) {
delay = std::atoi(argv[++i]);
} else if ((arg == "-p" || arg == "--pattern") && i + 1 < argc) {
pattern = argv[++i];
} else if ((arg == "-t" || arg == "--times") && i + 1 < argc) {
cycles = std::atoi(argv[++i]);
} else {
std::cerr << "Error: Unknown argument " << arg << std::endl;
printUsage(argv[0]);
return 1;
}
}
// 验证参数
if (colors.find(color) == colors.end()) {
std::cerr << "Error: Invalid color. Available: red, green, blue, yellow, white, black\n";
return 1;
}
if (ledIndex < 0 || ledIndex > 11) {
std::cerr << "Error: LED index must be 0-11\n";
return 1;
}
if (delay < 0) {
std::cerr << "Error: Delay must be non-negative\n";
return 1;
}
std::cout << "FaceLight Controller Starting...\n";
std::cout << "Mode: " << mode << ", Color: " << color << ", Delay: " << delay << "ms\n";
// 执行控制逻辑
if (mode == "all") {
// 全部LED使用同一颜色
std::cout << "Setting all LEDs to " << color << std::endl;
client.setAllLed(colors[color]);
client.sendCmd();
} else if (mode == "single") {
// 单个LED控制
std::cout << "Setting LED " << ledIndex << " to " << color << std::endl;
client.setAllLed(client.black); // 先关闭所有LED
client.setLedColor(ledIndex, colors[color]);
client.sendCmd();
} else if (mode == "cycle") {
// 颜色循环
std::cout << "Starting color cycle..." << std::endl;
std::vector<std::string> cycleColors = {"red", "green", "blue", "yellow", "white"};
int count = 0;
while (cycles == -1 || count < cycles) {
for (const auto& cycleColor : cycleColors) {
std::cout << "Cycle " << (count + 1) << ": " << cycleColor << std::endl;
client.setAllLed(colors[cycleColor]);
client.sendCmd();
usleep(delay * 1000); // 转换为微秒
}
if (cycles != -1) count++;
}
} else if (mode == "pattern") {
// 自定义模式
if (pattern.empty()) {
std::cerr << "Error: Pattern mode requires -p option\n";
return 1;
}
std::vector<std::pair<int, std::string>> ledPattern;
if (!parsePattern(pattern, ledPattern)) {
return 1;
}
std::cout << "Applying custom pattern..." << std::endl;
client.setAllLed(client.black); // 先关闭所有LED
for (const auto& led : ledPattern) {
int index = led.first;
const std::string& ledColor = led.second;
if (colors.find(ledColor) == colors.end()) {
std::cerr << "Error: Invalid color in pattern: " << ledColor << std::endl;
return 1;
}
std::cout << "Setting LED " << index << " to " << ledColor << std::endl;
client.setLedColor(index, colors[ledColor]);
}
client.sendCmd();
} else if (mode == "custom") {
// 原始自定义模式RGB交替
std::cout << "Applying RGB alternating pattern..." << std::endl;
for (int i = 0; i < 12; ++i) {
switch (i % 3) {
case 0:
client.setLedColor(i, client.red);
break;
case 1:
client.setLedColor(i, client.green);
break;
case 2:
client.setLedColor(i, client.blue);
break;
default:
break;
}
}
client.sendCmd();
} else {
std::cerr << "Error: Invalid mode. Available: all, single, cycle, custom, pattern\n";
return 1;
}
std::cout << "Command executed successfully!\n";
return 0;
}

@ -12,6 +12,7 @@ INCLUDEPATH += include
INCLUDEPATH += include/core INCLUDEPATH += include/core
INCLUDEPATH += include/ui INCLUDEPATH += include/ui
INCLUDEPATH += AudioModule INCLUDEPATH += AudioModule
INCLUDEPATH += FaceLightModule
# Build directories # Build directories
OBJECTS_DIR = build OBJECTS_DIR = build
@ -34,6 +35,7 @@ SOURCES += \
src/ui/components/RightFunctionPanel.cpp \ src/ui/components/RightFunctionPanel.cpp \
src/utils/SystemLogger.cpp \ src/utils/SystemLogger.cpp \
AudioModule/IntelligenceUI.cpp \ AudioModule/IntelligenceUI.cpp \
FaceLightModule/FaceLightControl.cpp \
styles/LeftPanelStyleManager.cpp \ styles/LeftPanelStyleManager.cpp \
styles/ModernStyleManager.cpp styles/ModernStyleManager.cpp
@ -51,6 +53,7 @@ HEADERS += \
include/ui/components/RightFunctionPanel.h \ include/ui/components/RightFunctionPanel.h \
include/utils/SystemLogger.h \ include/utils/SystemLogger.h \
AudioModule/IntelligenceUI.h \ AudioModule/IntelligenceUI.h \
FaceLightModule/FaceLightControl.h \
styles/LeftPanelStyleManager.h \ styles/LeftPanelStyleManager.h \
styles/ModernStyleManager.h styles/ModernStyleManager.h
@ -58,7 +61,8 @@ HEADERS += \
FORMS += \ FORMS += \
forms/main/MainWindow.ui \ forms/main/MainWindow.ui \
forms/dialogs/DeviceDialog.ui \ forms/dialogs/DeviceDialog.ui \
AudioModule/IntelligenceUI.ui AudioModule/IntelligenceUI.ui \
FaceLightModule/FaceLightControl.ui
# Default rules for deployment. # Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin qnx: target.path = /tmp/$${TARGET}/bin

@ -0,0 +1,366 @@
#include "FaceLightControl.h"
#include "ui_FaceLightControl.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QTimer>
#include <QDateTime>
#include <QProcess>
#include <QDebug>
FaceLightControl::FaceLightControl(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::FaceLightControl)
, sshProcess(nullptr)
, colorCycleTimer(nullptr)
, currentColorIndex(0)
, isCycling(false)
{
ui->setupUi(this);
// 初始化SSH设置
updateSshSettings();
// 初始化颜色循环
setupColorCycle();
// 连接信号槽
setupUI();
// 初始化状态
updateStatus("FaceLight控制系统已启动准备就绪");
ui->progressBar->setValue(0);
}
FaceLightControl::~FaceLightControl()
{
if (sshProcess && sshProcess->state() != QProcess::NotRunning) {
sshProcess->kill();
sshProcess->waitForFinished(3000);
}
if (colorCycleTimer) {
colorCycleTimer->stop();
}
delete ui;
}
void FaceLightControl::setupUI()
{
// 连接基础控制按钮信号槽
connect(ui->setAllLeds, &QPushButton::clicked, this, &FaceLightControl::on_setAllLeds_clicked);
connect(ui->setSingleLed, &QPushButton::clicked, this, &FaceLightControl::on_setSingleLed_clicked);
connect(ui->startColorCycle, &QPushButton::clicked, this, &FaceLightControl::on_startColorCycle_clicked);
connect(ui->stopColorCycle, &QPushButton::clicked, this, &FaceLightControl::on_stopColorCycle_clicked);
connect(ui->applyCustomPattern, &QPushButton::clicked, this, &FaceLightControl::on_applyCustomPattern_clicked);
connect(ui->turnOffAllLeds, &QPushButton::clicked, this, &FaceLightControl::on_turnOffAllLeds_clicked);
// 连接SSH设置按钮
connect(ui->saveSshSettings, &QPushButton::clicked, this, &FaceLightControl::on_saveSshSettings_clicked);
connect(ui->testConnection, &QPushButton::clicked, this, &FaceLightControl::on_testConnection_clicked);
// 连接高级控制按钮
connect(ui->rgbAlternating, &QPushButton::clicked, this, &FaceLightControl::on_rgbAlternating_clicked);
// 快速预设按钮连接 - 使用lambda表达式
connect(ui->preset1, &QPushButton::clicked, this, [this]() {
QString command = buildFaceLightCommand("all", "red");
executeSSHCommand(command, "预设1: 全部红色");
});
connect(ui->preset2, &QPushButton::clicked, this, [this]() {
QString command = buildFaceLightCommand("all", "blue");
executeSSHCommand(command, "预设2: 全部蓝色");
});
connect(ui->preset3, &QPushButton::clicked, this, [this]() {
QString command = buildFaceLightCommand("all", "green");
executeSSHCommand(command, "预设3: 全部绿色");
});
connect(ui->preset4, &QPushButton::clicked, this, [this]() {
QString command = buildFaceLightCommand("all", "white");
executeSSHCommand(command, "预设4: 全部白色");
});
}
void FaceLightControl::setupColorCycle()
{
cycleColors << "red" << "green" << "blue" << "yellow" << "white";
colorCycleTimer = new QTimer(this);
connect(colorCycleTimer, &QTimer::timeout, this, &FaceLightControl::onColorCycleTimer);
}
void FaceLightControl::executeSSHCommand(const QString &command, const QString &description)
{
if (sshProcess && sshProcess->state() != QProcess::NotRunning) {
updateStatus("上一个命令仍在执行中,请稍候...", true);
return;
}
if (!sshProcess) {
sshProcess = new QProcess(this);
connect(sshProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &FaceLightControl::onSshProcessFinished);
connect(sshProcess, &QProcess::errorOccurred,
this, &FaceLightControl::onSshProcessError);
}
currentCommand = description;
updateStatus(QString("正在执行: %1").arg(description));
ui->progressBar->setValue(25);
// 从UI获取最新的连接设置
updateSshSettings();
// 转义命令中的单引号
QString escapedCommand = command;
escapedCommand.replace("'", "'\"'\"'");
// 构建双跳SSH命令
QString fullCommand = QString(
"sshpass -p '%1' ssh -T -n -o StrictHostKeyChecking=no -o ConnectTimeout=10 %2@%3 "
"\"sshpass -p '%4' ssh -T -n -o StrictHostKeyChecking=no -o ConnectTimeout=10 %5@%6 'cd ~/Unitree/sdk/faceLightSDK_Nano/build && %7'\""
).arg(m_jumpPassword) // 跳板机密码
.arg(m_jumpUser) // 跳板机用户
.arg(m_jumpHost) // 跳板机IP
.arg(m_sshPassword) // 目标机密码
.arg(m_sshUser) // 目标机用户
.arg(m_sshHost) // 目标机IP
.arg(escapedCommand); // 要执行的命令
qDebug() << "执行SSH命令:" << fullCommand;
sshProcess->start("bash", QStringList() << "-c" << fullCommand);
}
QString FaceLightControl::buildFaceLightCommand(const QString &mode, const QString &color,
int ledIndex, int delay, int times, const QString &pattern)
{
QString command = "../bin/faceLightClient";
// 添加模式参数
command += QString(" -m %1").arg(mode);
// 添加颜色参数
if (!color.isEmpty()) {
command += QString(" -c %1").arg(color);
}
// 添加LED索引参数
if (ledIndex >= 0 && ledIndex <= 11) {
command += QString(" -i %1").arg(ledIndex);
}
// 添加延时参数
if (delay != 2000) {
command += QString(" -d %1").arg(delay);
}
// 添加循环次数参数
if (times != -1) {
command += QString(" -t %1").arg(times);
}
// 添加自定义图案参数
if (!pattern.isEmpty()) {
command += QString(" -p \"%1\"").arg(pattern);
}
return command;
}
void FaceLightControl::updateSshSettings()
{
// 目标机器狗设置
m_sshHost = ui->lineEditTargetIp->text();
m_sshUser = ui->lineEditTargetUsername->text();
m_sshPassword = ui->lineEditTargetPassword->text();
// 跳板机设置
m_jumpHost = ui->lineEditJumpIp->text();
m_jumpUser = ui->lineEditJumpUsername->text();
m_jumpPassword = ui->lineEditJumpPassword->text();
ui->connectionStatusLabel->setText(QString("连接链路: 本机 → %1@%2 → %3@%4")
.arg(m_jumpUser).arg(m_jumpHost)
.arg(m_sshUser).arg(m_sshHost));
}
void FaceLightControl::on_setAllLeds_clicked()
{
QString color = ui->colorComboBox->currentText().toLower();
QString command = buildFaceLightCommand("all", color);
executeSSHCommand(command, QString("设置所有LED为%1色").arg(color));
}
void FaceLightControl::on_setSingleLed_clicked()
{
QString color = ui->colorComboBox->currentText().toLower();
int ledIndex = ui->ledIndexSpinBox->value();
QString command = buildFaceLightCommand("single", color, ledIndex);
executeSSHCommand(command, QString("设置LED %1为%2色").arg(ledIndex).arg(color));
}
void FaceLightControl::on_startColorCycle_clicked()
{
if (isCycling) {
updateStatus("颜色循环已在运行中", true);
return;
}
int delay = ui->cycleDelaySpinBox->value();
int times = ui->cycleTimesSpinBox->value();
QString command = buildFaceLightCommand("cycle", "", -1, delay, times);
executeSSHCommand(command, QString("启动颜色循环 (延时:%1ms, 次数:%2)").arg(delay).arg(times == -1 ? "无限" : QString::number(times)));
}
void FaceLightControl::on_stopColorCycle_clicked()
{
// 发送黑色命令来停止循环
QString command = buildFaceLightCommand("all", "black");
executeSSHCommand(command, "停止颜色循环");
if (colorCycleTimer->isActive()) {
colorCycleTimer->stop();
isCycling = false;
updateStatus("本地颜色循环已停止");
}
}
void FaceLightControl::on_applyCustomPattern_clicked()
{
QString pattern = ui->patternLineEdit->text().trimmed();
if (pattern.isEmpty()) {
updateStatus("错误: 请输入自定义图案", true);
return;
}
QString command = buildFaceLightCommand("pattern", "", -1, 2000, -1, pattern);
executeSSHCommand(command, QString("应用自定义图案: %1").arg(pattern));
}
void FaceLightControl::on_turnOffAllLeds_clicked()
{
QString command = buildFaceLightCommand("all", "black");
executeSSHCommand(command, "关闭所有LED");
}
void FaceLightControl::on_rgbAlternating_clicked()
{
QString command = buildFaceLightCommand("custom");
executeSSHCommand(command, "应用RGB交替模式");
}
void FaceLightControl::on_saveSshSettings_clicked()
{
updateSshSettings();
updateStatus("SSH连接设置已更新并保存");
}
void FaceLightControl::on_testConnection_clicked()
{
QString command = "echo 'FaceLight连接测试成功'";
executeSSHCommand(command, "测试SSH连接");
}
void FaceLightControl::onColorCycleTimer()
{
if (!isCycling || cycleColors.isEmpty()) {
return;
}
QString color = cycleColors[currentColorIndex];
QString command = buildFaceLightCommand("all", color);
executeSSHCommand(command, QString("循环显示: %1").arg(color));
currentColorIndex = (currentColorIndex + 1) % cycleColors.size();
}
void FaceLightControl::onSshProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
ui->progressBar->setValue(100);
if (exitStatus == QProcess::NormalExit && exitCode == 0) {
updateStatus(QString("%1 - 执行成功").arg(currentCommand));
} else {
updateStatus(QString("%1 - 执行失败 (退出码: %2)").arg(currentCommand).arg(exitCode), true);
}
// 读取命令输出
if (sshProcess) {
QByteArray output = sshProcess->readAllStandardOutput();
QByteArray error = sshProcess->readAllStandardError();
if (!output.isEmpty()) {
updateStatus(QString("输出: %1").arg(QString::fromUtf8(output).trimmed()));
}
if (!error.isEmpty()) {
updateStatus(QString("错误: %1").arg(QString::fromUtf8(error).trimmed()), true);
}
}
// 清理进程
if (sshProcess) {
sshProcess->kill();
sshProcess->waitForFinished(1000);
sshProcess->deleteLater();
sshProcess = nullptr;
}
// 重置进度条
QTimer::singleShot(2000, [this]() {
ui->progressBar->setValue(0);
});
}
void FaceLightControl::onSshProcessError(QProcess::ProcessError error)
{
ui->progressBar->setValue(0);
QString errorString;
switch (error) {
case QProcess::FailedToStart:
errorString = "命令启动失败";
break;
case QProcess::Crashed:
errorString = "命令执行崩溃";
break;
case QProcess::Timedout:
errorString = "命令执行超时";
break;
default:
errorString = "未知错误";
break;
}
updateStatus(QString("%1 - %2").arg(currentCommand).arg(errorString), true);
}
void FaceLightControl::updateStatus(const QString &message, bool isError)
{
QString timestamp = QDateTime::currentDateTime().toString("hh:mm:ss");
QString logMessage = QString("[%1] %2").arg(timestamp).arg(message);
if (isError) {
ui->logTextEdit->setTextColor(QColor(255, 100, 100));
} else {
ui->logTextEdit->setTextColor(QColor(100, 255, 100));
}
ui->logTextEdit->append(logMessage);
ui->logTextEdit->setTextColor(QColor(220, 230, 240)); // 重置颜色
// 自动滚动到底部
ui->logTextEdit->moveCursor(QTextCursor::End);
}
void FaceLightControl::on_quickPresets_clicked()
{
// 该槽为占位实现,防止链接错误。
// 如果需要统一触发多个预设,可在此调用相应的命令序列。
updateStatus("快速预设触发(占位)");
}

@ -0,0 +1,94 @@
#ifndef FACELIGHTCONTROL_H
#define FACELIGHTCONTROL_H
#include <QMainWindow>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QProcess>
#include <QMessageBox>
#include <QDebug>
#include <QComboBox>
#include <QTextEdit>
#include <QProgressBar>
#include <QTimer>
#include <QSpinBox>
#include <QSlider>
#include <QGroupBox>
#include <QLineEdit>
#include <QFormLayout>
QT_BEGIN_NAMESPACE
namespace Ui {
class FaceLightControl;
}
QT_END_NAMESPACE
class FaceLightControl : public QMainWindow
{
Q_OBJECT
public:
FaceLightControl(QWidget *parent = nullptr);
~FaceLightControl();
private slots:
// 基础控制按钮
void on_setAllLeds_clicked();
void on_setSingleLed_clicked();
void on_startColorCycle_clicked();
void on_stopColorCycle_clicked();
void on_applyCustomPattern_clicked();
void on_turnOffAllLeds_clicked();
// SSH连接设置
void on_saveSshSettings_clicked();
void on_testConnection_clicked();
// 高级控制
void on_rgbAlternating_clicked();
void on_quickPresets_clicked();
// SSH进程处理
void onSshProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
void onSshProcessError(QProcess::ProcessError error);
// 颜色循环定时器
void onColorCycleTimer();
private:
Ui::FaceLightControl *ui;
QProcess *sshProcess;
QString currentCommand;
// SSH连接信息
QString m_sshHost;
QString m_sshUser;
QString m_sshPassword;
QString m_jumpHost;
QString m_jumpUser;
QString m_jumpPassword;
// 颜色循环控制
QTimer *colorCycleTimer;
QStringList cycleColors;
int currentColorIndex;
bool isCycling;
// 核心方法
void executeSSHCommand(const QString &command, const QString &description);
void updateSshSettings();
// UI设置和状态更新
void setupUI();
void updateStatus(const QString &message, bool isError = false);
void setupColorCycle();
// 命令构建方法
QString buildFaceLightCommand(const QString &mode, const QString &color = "",
int ledIndex = -1, int delay = 2000,
int times = -1, const QString &pattern = "");
};
#endif // FACELIGHTCONTROL_H

@ -0,0 +1,702 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FaceLightControl</class>
<widget class="QMainWindow" name="FaceLightControl">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1000</width>
<height>900</height>
</rect>
</property>
<property name="windowTitle">
<string>机器狗面部灯光控制系统</string>
</property>
<property name="styleSheet">
<string notr="true">QMainWindow {
background-color: rgb(24, 33, 45);
}
QPushButton {
background-color: rgb(30, 44, 62);
color: rgb(220, 230, 240);
border: 2px solid rgba(0, 168, 255, 0.5);
border-radius: 8px;
padding: 12px 20px;
font-size: 14px;
font-weight: bold;
min-height: 35px;
}
QPushButton:hover {
background-color: rgb(50, 70, 95);
border: 2px solid rgba(0, 168, 255, 0.8);
}
QPushButton:pressed {
background-color: rgb(40, 60, 85);
border: 2px solid rgba(0, 168, 255, 1.0);
}
QLabel {
color: rgb(220, 230, 240);
font-size: 14px;
}
QComboBox, QSpinBox, QLineEdit {
background-color: rgb(30, 44, 62);
color: rgb(220, 230, 240);
border: 2px solid rgba(0, 168, 255, 0.5);
border-radius: 5px;
padding: 8px;
font-size: 14px;
}
QTextEdit {
background-color: rgb(15, 22, 32);
color: rgb(220, 230, 240);
border: 2px solid rgba(0, 168, 255, 0.3);
border-radius: 5px;
font-family: "Courier New", monospace;
font-size: 12px;
}
QProgressBar {
border: 2px solid rgba(0, 168, 255, 0.5);
border-radius: 5px;
text-align: center;
background-color: rgb(30, 44, 62);
color: rgb(220, 230, 240);
}
QProgressBar::chunk {
background-color: rgba(0, 168, 255, 0.8);
border-radius: 3px;
}
QGroupBox {
font-size: 16px;
font-weight: bold;
color: rgb(0, 168, 255);
border: 2px solid rgba(0, 168, 255, 0.4);
border-radius: 10px;
margin-top: 15px;
padding-top: 10px;
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top center;
padding: 0 15px;
background-color: rgb(24, 33, 45);
}</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>20</number>
</property>
<property name="leftMargin">
<number>30</number>
</property>
<property name="topMargin">
<number>20</number>
</property>
<property name="rightMargin">
<number>30</number>
</property>
<property name="bottomMargin">
<number>20</number>
</property>
<item>
<widget class="QLabel" name="titleLabel">
<property name="text">
<string>💡 机器狗面部灯光控制系统</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="styleSheet">
<string notr="true">QLabel {
color: rgb(0, 168, 255);
font-size: 32px;
font-weight: bold;
padding: 20px;
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
stop:0 rgba(0, 168, 255, 0.1),
stop:1 rgba(0, 120, 180, 0.1));
border: 2px solid rgba(0, 168, 255, 0.3);
border-radius: 15px;
}</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="sshSettingsGroup">
<property name="title">
<string>🔗 SSH连接设置</string>
</property>
<layout class="QVBoxLayout" name="sshLayout">
<item>
<layout class="QHBoxLayout" name="connectionLayout">
<item>
<widget class="QGroupBox" name="jumpHostGroup">
<property name="title">
<string>跳板机设置</string>
</property>
<property name="styleSheet">
<string notr="true">QGroupBox { font-size: 14px; color: rgb(180, 190, 200); }</string>
</property>
<layout class="QFormLayout" name="jumpFormLayout">
<item row="0" column="0">
<widget class="QLabel" name="jumpIpLabel">
<property name="text">
<string>跳板机IP:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEditJumpIp">
<property name="text">
<string>192.168.12.1</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="jumpUserLabel">
<property name="text">
<string>用户名:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEditJumpUsername">
<property name="text">
<string>pi</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="jumpPasswordLabel">
<property name="text">
<string>密码:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEditJumpPassword">
<property name="text">
<string>123</string>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="targetHostGroup">
<property name="title">
<string>目标机器狗设置</string>
</property>
<property name="styleSheet">
<string notr="true">QGroupBox { font-size: 14px; color: rgb(180, 190, 200); }</string>
</property>
<layout class="QFormLayout" name="targetFormLayout">
<item row="0" column="0">
<widget class="QLabel" name="targetIpLabel">
<property name="text">
<string>机器狗IP:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEditTargetIp">
<property name="text">
<string>192.168.123.13</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="targetUserLabel">
<property name="text">
<string>用户名:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEditTargetUsername">
<property name="text">
<string>unitree</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="targetPasswordLabel">
<property name="text">
<string>密码:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEditTargetPassword">
<property name="text">
<string>123</string>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="sshButtonLayout">
<item>
<widget class="QPushButton" name="saveSshSettings">
<property name="text">
<string>💾 保存设置</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="testConnection">
<property name="text">
<string>🔍 测试连接</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="connectionStatusLabel">
<property name="text">
<string>连接状态: 等待设置...</string>
</property>
<property name="styleSheet">
<string notr="true">color: rgb(160, 170, 180); font-size: 12px;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="mainControlLayout">
<item>
<widget class="QGroupBox" name="basicControlGroup">
<property name="title">
<string>🎨 基础控制</string>
</property>
<layout class="QVBoxLayout" name="basicControlLayout">
<item>
<layout class="QFormLayout" name="colorFormLayout">
<item row="0" column="0">
<widget class="QLabel" name="colorLabel">
<property name="text">
<string>颜色选择:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="colorComboBox">
<item>
<property name="text">
<string>Red</string>
</property>
</item>
<item>
<property name="text">
<string>Green</string>
</property>
</item>
<item>
<property name="text">
<string>Blue</string>
</property>
</item>
<item>
<property name="text">
<string>Yellow</string>
</property>
</item>
<item>
<property name="text">
<string>White</string>
</property>
</item>
<item>
<property name="text">
<string>Black</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="ledIndexLabel">
<property name="text">
<string>LED索引:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="ledIndexSpinBox">
<property name="maximum">
<number>11</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="setAllLeds">
<property name="text">
<string>💡 设置所有LED</string>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
background-color: rgb(45, 125, 65);
font-size: 16px;
font-weight: bold;
}
QPushButton:hover { background-color: rgb(65, 145, 85); }
QPushButton:pressed { background-color: rgb(55, 135, 75); }</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="setSingleLed">
<property name="text">
<string>🔆 设置单个LED</string>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
background-color: rgb(85, 125, 165);
font-size: 16px;
font-weight: bold;
}
QPushButton:hover { background-color: rgb(105, 145, 185); }
QPushButton:pressed { background-color: rgb(95, 135, 175); }</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="turnOffAllLeds">
<property name="text">
<string>🌑 关闭所有LED</string>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
background-color: rgb(120, 60, 60);
font-size: 16px;
font-weight: bold;
}
QPushButton:hover { background-color: rgb(140, 80, 80); }
QPushButton:pressed { background-color: rgb(130, 70, 70); }</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="advancedControlGroup">
<property name="title">
<string>⚡ 高级控制</string>
</property>
<layout class="QVBoxLayout" name="advancedControlLayout">
<item>
<widget class="QLabel" name="cycleLabel">
<property name="text">
<string>🔄 颜色循环设置:</string>
</property>
<property name="styleSheet">
<string notr="true">font-weight: bold; color: rgb(0, 168, 255);</string>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="cycleFormLayout">
<item row="0" column="0">
<widget class="QLabel" name="cycleDelayLabel">
<property name="text">
<string>延时(ms):</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="cycleDelaySpinBox">
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>10000</number>
</property>
<property name="value">
<number>1000</number>
</property>
<property name="suffix">
<string> ms</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="cycleTimesLabel">
<property name="text">
<string>循环次数:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="cycleTimesSpinBox">
<property name="minimum">
<number>-1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>5</number>
</property>
<property name="specialValueText">
<string>无限循环</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="cycleButtonLayout">
<item>
<widget class="QPushButton" name="startColorCycle">
<property name="text">
<string>▶️ 开始循环</string>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
background-color: rgb(45, 125, 65);
}
QPushButton:hover { background-color: rgb(65, 145, 85); }</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stopColorCycle">
<property name="text">
<string>⏹️ 停止循环</string>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
background-color: rgb(165, 85, 45);
}
QPushButton:hover { background-color: rgb(185, 105, 65); }</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="patternLabel">
<property name="text">
<string>🎭 自定义图案:</string>
</property>
<property name="styleSheet">
<string notr="true">font-weight: bold; color: rgb(0, 168, 255);</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="patternLineEdit">
<property name="placeholderText">
<string>例如: 0:red,3:green,6:blue</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="applyCustomPattern">
<property name="text">
<string>🎨 应用自定义图案</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="rgbAlternating">
<property name="text">
<string>🌈 RGB交替模式</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="presetGroup">
<property name="title">
<string>⚡ 快速预设</string>
</property>
<layout class="QVBoxLayout" name="presetLayout">
<item>
<widget class="QPushButton" name="preset1">
<property name="text">
<string>🔴 预设1: 红色</string>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
background-color: rgb(180, 60, 60);
}
QPushButton:hover { background-color: rgb(200, 80, 80); }</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="preset2">
<property name="text">
<string>🔵 预设2: 蓝色</string>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
background-color: rgb(60, 60, 180);
}
QPushButton:hover { background-color: rgb(80, 80, 200); }</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="preset3">
<property name="text">
<string>🟢 预设3: 绿色</string>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
background-color: rgb(60, 180, 60);
}
QPushButton:hover { background-color: rgb(80, 200, 80); }</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="preset4">
<property name="text">
<string>⚪ 预设4: 白色</string>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
background-color: rgb(140, 140, 140);
color: rgb(30, 30, 30);
}
QPushButton:hover { background-color: rgb(160, 160, 160); }</string>
</property>
</widget>
</item>
<item>
<spacer name="presetSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>0</number>
</property>
<property name="textVisible">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="logLabel">
<property name="text">
<string>📋 执行日志:</string>
</property>
<property name="styleSheet">
<string notr="true">font-size: 16px; font-weight: bold; color: rgb(0, 168, 255);</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="logTextEdit">
<property name="minimumSize">
<size>
<width>0</width>
<height>200</height>
</size>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1000</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>

@ -183,6 +183,11 @@ signals:
*/ */
void openIntelligenceUI(); void openIntelligenceUI();
/**
* @brief
*/
void openFaceLightUI();
// 敌情统计模块信号 // 敌情统计模块信号
/** /**
* @brief * @brief
@ -247,6 +252,11 @@ private slots:
*/ */
void onOpenIntelligenceUI(); void onOpenIntelligenceUI();
/**
* @brief
*/
void onOpenFaceLightUI();
/** /**
* @brief * @brief
*/ */
@ -299,6 +309,7 @@ private:
// 情报传输模块 // 情报传输模块
ModuleCard *m_intelligenceCard; ///< 情报模块卡片 ModuleCard *m_intelligenceCard; ///< 情报模块卡片
QPushButton *m_voiceCallBtn; ///< 音频控制按钮 QPushButton *m_voiceCallBtn; ///< 音频控制按钮
QPushButton *m_faceLightBtn; ///< 面部灯光控制按钮
// 敌情统计模块 // 敌情统计模块
ModuleCard *m_statsCard; ///< 统计模块卡片 ModuleCard *m_statsCard; ///< 统计模块卡片

@ -40,6 +40,7 @@
// 自定义模块头文件 // 自定义模块头文件
#include "AudioModule/IntelligenceUI.h" #include "AudioModule/IntelligenceUI.h"
#include "FaceLightModule/FaceLightControl.h"
#include "ui/components/DeviceListPanel.h" #include "ui/components/DeviceListPanel.h"
#include "ui/components/SystemLogPanel.h" #include "ui/components/SystemLogPanel.h"
#include "ui/components/RightFunctionPanel.h" #include "ui/components/RightFunctionPanel.h"
@ -192,6 +193,11 @@ private slots:
*/ */
void onIntelligenceClicked(); void onIntelligenceClicked();
/**
* @brief FaceLight
*/
void onFaceLightClicked();
/** /**
* @brief * @brief
* @param deviceId ID * @param deviceId ID
@ -340,6 +346,7 @@ private:
private: private:
Ui::MainWindow *m_ui; ///< UI界面指针 Ui::MainWindow *m_ui; ///< UI界面指针
IntelligenceUI *m_intelligenceUI; ///< 情报传达界面指针 IntelligenceUI *m_intelligenceUI; ///< 情报传达界面指针
FaceLightControl *m_faceLightControl; ///< 面部灯光控制界面指针
DeviceListPanel *m_deviceListPanel; ///< 设备列表面板组件 DeviceListPanel *m_deviceListPanel; ///< 设备列表面板组件
SystemLogPanel *m_systemLogPanel; ///< 系统日志面板组件 SystemLogPanel *m_systemLogPanel; ///< 系统日志面板组件
RightFunctionPanel *m_rightFunctionPanel; ///< 右侧功能面板组件 RightFunctionPanel *m_rightFunctionPanel; ///< 右侧功能面板组件

@ -408,8 +408,6 @@ void DeviceCard::updateDeviceStatus(DeviceStatus status)
} }
} }
void DeviceCard::updateLocation(double longitude, double latitude) void DeviceCard::updateLocation(double longitude, double latitude)
{ {
m_deviceInfo.longitude = longitude; m_deviceInfo.longitude = longitude;

@ -279,14 +279,20 @@ void RightFunctionPanel::setupIntelligenceModule()
m_intelligenceCard->setProperty("data-module", "intelligence"); m_intelligenceCard->setProperty("data-module", "intelligence");
// 情报传达说明 // 情报传达说明
QLabel *descLabel = new QLabel("🎯 远程音频控制系统"); QLabel *descLabel = new QLabel("🎯 远程控制系统");
descLabel->setObjectName("intelligence-description"); descLabel->setObjectName("intelligence-description");
descLabel->setAlignment(Qt::AlignCenter); descLabel->setAlignment(Qt::AlignCenter);
descLabel->setStyleSheet("color: #00a8ff; font-size: 14px; font-weight: bold; padding: 8px;"); descLabel->setStyleSheet("color: #00a8ff; font-size: 14px; font-weight: bold; padding: 8px;");
m_intelligenceCard->addContent(descLabel); m_intelligenceCard->addContent(descLabel);
// 主功能按钮 - 打开音频控制界面 // 按钮布局容器
m_voiceCallBtn = new QPushButton("🔊 打开音频控制界面"); QWidget *buttonWidget = new QWidget();
QVBoxLayout *buttonLayout = new QVBoxLayout(buttonWidget);
buttonLayout->setSpacing(12);
buttonLayout->setContentsMargins(0, 0, 0, 0);
// 音频控制按钮
m_voiceCallBtn = new QPushButton("🔊 音频控制模块");
m_voiceCallBtn->setObjectName("FunctionBtn"); m_voiceCallBtn->setObjectName("FunctionBtn");
m_voiceCallBtn->setProperty("class", "primary-large"); m_voiceCallBtn->setProperty("class", "primary-large");
m_voiceCallBtn->setMinimumHeight(55); m_voiceCallBtn->setMinimumHeight(55);
@ -311,11 +317,41 @@ void RightFunctionPanel::setupIntelligenceModule()
"}" "}"
); );
// 面部灯光控制按钮
m_faceLightBtn = new QPushButton("💡 灯光控制模块");
m_faceLightBtn->setObjectName("FunctionBtn");
m_faceLightBtn->setProperty("class", "primary-large");
m_faceLightBtn->setMinimumHeight(55);
m_faceLightBtn->setStyleSheet(
"QPushButton {"
" background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
" stop:0 #ffa502, stop:1 #ff6348);"
" color: white;"
" font-size: 16px;"
" font-weight: bold;"
" border: 2px solid #ffa502;"
" border-radius: 8px;"
" padding: 12px;"
"}"
"QPushButton:hover {"
" background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
" stop:0 #ff6348, stop:1 #e55039);"
"}"
"QPushButton:pressed {"
" background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,"
" stop:0 #e55039, stop:1 #c44569);"
"}"
);
connect(m_voiceCallBtn, &QPushButton::clicked, this, &RightFunctionPanel::onOpenIntelligenceUI); 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->setObjectName("feature-list");
featureLabel->setAlignment(Qt::AlignLeft); featureLabel->setAlignment(Qt::AlignLeft);
featureLabel->setStyleSheet("color: #b0b0b0; font-size: 12px; padding: 10px; line-height: 1.4;"); featureLabel->setStyleSheet("color: #b0b0b0; font-size: 12px; padding: 10px; line-height: 1.4;");
@ -847,6 +883,11 @@ void RightFunctionPanel::onOpenIntelligenceUI()
emit openIntelligenceUI(); emit openIntelligenceUI();
} }
void RightFunctionPanel::onOpenFaceLightUI()
{
emit openFaceLightUI();
}
void RightFunctionPanel::onRefreshStats() void RightFunctionPanel::onRefreshStats()
{ {
emit refreshEnemyStats(); emit refreshEnemyStats();

@ -55,6 +55,7 @@ MainWindow::MainWindow(QWidget *parent)
, m_rightFunctionPanel(nullptr) , m_rightFunctionPanel(nullptr)
, m_leftPanelSplitter(nullptr) , m_leftPanelSplitter(nullptr)
, m_intelligenceUI(nullptr) , m_intelligenceUI(nullptr)
, m_faceLightControl(nullptr)
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
@ -76,6 +77,10 @@ MainWindow::~MainWindow()
delete m_intelligenceUI; delete m_intelligenceUI;
m_intelligenceUI = nullptr; m_intelligenceUI = nullptr;
} }
if (m_faceLightControl) {
delete m_faceLightControl;
m_faceLightControl = nullptr;
}
delete m_ui; delete m_ui;
} }
@ -235,6 +240,8 @@ void MainWindow::setupRightFunctionPanel()
// 情报传输模块信号 // 情报传输模块信号
connect(m_rightFunctionPanel, &RightFunctionPanel::openIntelligenceUI, connect(m_rightFunctionPanel, &RightFunctionPanel::openIntelligenceUI,
this, &MainWindow::onIntelligenceClicked); this, &MainWindow::onIntelligenceClicked);
connect(m_rightFunctionPanel, &RightFunctionPanel::openFaceLightUI,
this, &MainWindow::onFaceLightClicked);
// 敌情统计模块信号 // 敌情统计模块信号
connect(m_rightFunctionPanel, &RightFunctionPanel::refreshEnemyStats, connect(m_rightFunctionPanel, &RightFunctionPanel::refreshEnemyStats,
@ -890,6 +897,16 @@ void MainWindow::onIntelligenceClicked()
m_intelligenceUI->raise(); 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) void MainWindow::onDeviceSelected(const QString &deviceId)
{ {
qDebug() << "Device selected:" << deviceId; qDebug() << "Device selected:" << deviceId;
@ -1271,8 +1288,6 @@ void MainWindow::onStopPersonRecognition()
// TODO: 实现停止人物识别功能 // TODO: 实现停止人物识别功能
} }
void MainWindow::onRefreshEnemyStats() void MainWindow::onRefreshEnemyStats()
{ {
qDebug() << "Refreshing enemy statistics..."; qDebug() << "Refreshing enemy statistics...";

Loading…
Cancel
Save