feat:初始化wuhan_QT界面代码
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(ls -la \"g:/workspace/a6_haisi/haisi22Ap10/qt/wuhan/wuhan/\")",
|
||||
"Read(//g/workspace/a6_haisi/haisi22Ap10/qt/wuhan/wuhan/**)",
|
||||
"Read(//c//**)",
|
||||
"Read(//c/Qt/**)",
|
||||
"Bash(cd \"g:/workspace/a6_haisi\" && find . -maxdepth 4 -iname \"*通信协议*\" -o -iname \"*0708*\" -o -iname \"*协议*\" 2>/dev/null | head -40; echo \"=== all docs in workspace root ===\"; ls -la \"g:/workspace/a6_haisi/haisi22Ap10/\" 2>/dev/null; echo \"=== PasswordLogin / RobotControl ===\"; ls -la \"g:/workspace/a6_haisi/haisi22Ap10/qt/wuhan/wuhan/PasswordLogin/\" \"g:/workspace/a6_haisi/haisi22Ap10/qt/wuhan/wuhan/RobotControl/\" 2>/dev/null)",
|
||||
"Read(//g/workspace/a6_haisi/**)",
|
||||
"Read(//g/workspace/a6_haisi/haisi22Ap10/**)",
|
||||
"Bash(ls \"F:/QT/5.15.2/mingw81_32/bin/qmake.exe\" \"F:/QT/5.15.2/mingw81_32/bin/moc.exe\" \"F:/QT/Tools/mingw810_32/bin/g++.exe\" \"F:/QT/Tools/mingw810_32/bin/mingw32-make.exe\" 2>&1)",
|
||||
"Read(//f/QT/5.15.2/mingw81_32/bin/**)",
|
||||
"Bash(ls \"F:/QT/5.15.2/mingw81_32/plugins/platforms/\" 2>&1)",
|
||||
"Read(//f/QT/5.15.2/mingw81_32/plugins/platforms/**)",
|
||||
"Bash(taskkill //F //IM wuhan.exe)",
|
||||
"Bash(tasklist)",
|
||||
"Bash(sed -i 's/setPixelSize\\(20\\)/setPixelSize\\(24\\)/; s/setFixedHeight\\(44\\)/setFixedHeight\\(52\\)/; s/m_radius = 16/m_radius = 18/' widgets/ledindicator.cpp)",
|
||||
"Bash(sed -i 's/font-size:32px/font-size:40px/; s/font-size:22px/font-size:26px/' widgets/titlebar.cpp)",
|
||||
"Bash(sed -i 's/font-size:18px/font-size:22px/; s/font-size:20px/font-size:24px/g' widgets/statusstrip.cpp)",
|
||||
"Bash(sed -i 's/font-size:20px/font-size:22px/' widgets/faulttable.cpp)",
|
||||
"Bash(sed -i 's/font-size:26px/font-size:30px/' widgets/alarmbanner.cpp)",
|
||||
"Bash(sed -i 's/font-size:20px;font-weight:700/font-size:24px;font-weight:700/; s/color:%1;font-size:20px;/color:%1;font-size:22px;/; s/font-size:56px;font-weight:700/font-size:64px;font-weight:700/; s/font-size:26px;font-weight:700/font-size:30px;font-weight:700/' widgets/datacard.cpp)",
|
||||
"Bash(sed -i 's/font-size:44px/font-size:52px/; s/font-size:40px/font-size:44px/g; s/font-size:18px/font-size:22px/' widgets/paramcontrol.cpp)",
|
||||
"Bash(sed -i 's/font-size:18px/font-size:22px/g; s/font-size:20px/font-size:24px/g' pages/armpage.cpp)",
|
||||
"Bash(sed -i 's/font-size:22px/font-size:26px/' pages/chassispage.cpp)",
|
||||
"Bash(sed -i 's/font-size:20px/font-size:24px/' pages/faultquerypage.cpp)",
|
||||
"Bash(cd /tmp)",
|
||||
"Bash(rm -rf \"g:/workspace/a6_haisi/haisi22Ap10/qt/wuhan/wuhan/Ui_wuhan/build/manual\")"
|
||||
]
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
# Qt Creator 自动生成的本地配置文件(每个人、每台电脑都不同,绝对不能上传)
|
||||
*.user
|
||||
*.user.*
|
||||
*.suo
|
||||
*.tasks
|
||||
CMakeLists.txt.user
|
||||
|
||||
# 编译输出目录(Qt Creator 默认生成的外部 build 文件夹)
|
||||
build-*/
|
||||
|
||||
# 临时编译文件与中间件
|
||||
*.o
|
||||
*.obj
|
||||
*.moc
|
||||
moc_*.cpp
|
||||
qrc_*.cpp
|
||||
ui_*.h
|
||||
*.pdb
|
||||
*.ilk
|
||||
*.idb
|
||||
|
||||
# 最终生成的可执行文件与动态库
|
||||
/debug/
|
||||
/release/
|
||||
*.exe
|
||||
*.dll
|
||||
*.so
|
||||
*.a
|
||||
*.lib
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "windows-gcc-x64",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"compilerPath": "gcc",
|
||||
"cStandard": "${default}",
|
||||
"cppStandard": "${default}",
|
||||
"intelliSenseMode": "windows-gcc-x64",
|
||||
"compilerArgs": [
|
||||
""
|
||||
]
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "C/C++ Runner: Debug Session",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"cwd": "g:/workspace/a6_haisi/haisi22Ap10/qt/wuhan/wuhan/Ui_wuhan",
|
||||
"program": "g:/workspace/a6_haisi/haisi22Ap10/qt/wuhan/wuhan/Ui_wuhan/build/Debug/outDebug",
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+59
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"C_Cpp_Runner.cCompilerPath": "gcc",
|
||||
"C_Cpp_Runner.cppCompilerPath": "g++",
|
||||
"C_Cpp_Runner.debuggerPath": "gdb",
|
||||
"C_Cpp_Runner.cStandard": "",
|
||||
"C_Cpp_Runner.cppStandard": "",
|
||||
"C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat",
|
||||
"C_Cpp_Runner.useMsvc": false,
|
||||
"C_Cpp_Runner.warnings": [
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Wpedantic",
|
||||
"-Wshadow",
|
||||
"-Wformat=2",
|
||||
"-Wcast-align",
|
||||
"-Wconversion",
|
||||
"-Wsign-conversion",
|
||||
"-Wnull-dereference"
|
||||
],
|
||||
"C_Cpp_Runner.msvcWarnings": [
|
||||
"/W4",
|
||||
"/permissive-",
|
||||
"/w14242",
|
||||
"/w14287",
|
||||
"/w14296",
|
||||
"/w14311",
|
||||
"/w14826",
|
||||
"/w44062",
|
||||
"/w44242",
|
||||
"/w14905",
|
||||
"/w14906",
|
||||
"/w14263",
|
||||
"/w44265",
|
||||
"/w14928"
|
||||
],
|
||||
"C_Cpp_Runner.enableWarnings": true,
|
||||
"C_Cpp_Runner.warningsAsError": false,
|
||||
"C_Cpp_Runner.compilerArgs": [],
|
||||
"C_Cpp_Runner.linkerArgs": [],
|
||||
"C_Cpp_Runner.includePaths": [],
|
||||
"C_Cpp_Runner.includeSearch": [
|
||||
"*",
|
||||
"**/*"
|
||||
],
|
||||
"C_Cpp_Runner.excludeSearch": [
|
||||
"**/build",
|
||||
"**/build/**",
|
||||
"**/.*",
|
||||
"**/.*/**",
|
||||
"**/.vscode",
|
||||
"**/.vscode/**"
|
||||
],
|
||||
"C_Cpp_Runner.useAddressSanitizer": false,
|
||||
"C_Cpp_Runner.useUndefinedSanitizer": false,
|
||||
"C_Cpp_Runner.useLeakSanitizer": false,
|
||||
"C_Cpp_Runner.showCompilationTime": false,
|
||||
"C_Cpp_Runner.useLinkTimeOptimization": false,
|
||||
"C_Cpp_Runner.msvcSecureNoWarnings": false
|
||||
}
|
||||
Binary file not shown.
+1241
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,57 @@
|
||||
# 图数一体机遥控端 QT 界面(wuhan)
|
||||
|
||||
依据《QT界面详细设计说明书.md》实现的“玉兔工业无线遥控器(YTZT6K8EART2-aL25)”遥控端界面,
|
||||
覆盖 ③开机密码(含密码警告/密码管理登录/密码管理/密码重置)④自检 ⑤作业选择 ⑥机器人底盘
|
||||
⑦机械臂 ⑧气体检测仪 ⑨手动消除 ⑩手动消毒 ⑪调试维护 ⑫故障查询 共 10 个界面,
|
||||
并配套 **UDP 收包 / 发包通信** 与内置模拟车载端。
|
||||
|
||||
## 环境与构建
|
||||
|
||||
- Qt 5.15.2 MinGW 32-bit(`F:\QT\5.15.2\mingw81_32`),编译套件 `Desktop Qt 5.15.2 MinGW 32-bit`。
|
||||
- 用 Qt Creator 打开 `wuhan.pro` 直接构建运行即可(qmake 工程,`QT += network`)。
|
||||
|
||||
命令行构建示例:
|
||||
|
||||
```bash
|
||||
export PATH="/f/QT/Tools/mingw810_32/bin:/f/QT/5.15.2/mingw81_32/bin:$PATH"
|
||||
mkdir -p build && cd build
|
||||
qmake ../wuhan.pro -spec win32-g++ "CONFIG+=debug"
|
||||
mingw32-make -j4
|
||||
```
|
||||
|
||||
运行:`debug/wuhan.exe`(1920×1080 全屏无边框)。
|
||||
|
||||
## 运行说明
|
||||
|
||||
- 开机密码默认 **6789**(可在“忘记密码/修改密码 → 密码管理登录(管理员密码 6789)→ 密码管理 → 重置密码”中修改)。
|
||||
- 密码正确后进入自检,自检完成 2 秒自动进入“作业选择”;自检异常时可“忽略故障”继续。
|
||||
- 底部状态条上的**模式徽标可点击**(或按键盘 **M**)在“行车模式 / 机械臂模式”间切换;
|
||||
行车模式操作底盘,机械臂模式操作机械臂。
|
||||
- 软急停:各页顶条右上角“急停”按钮,或按键盘 **E**;急停后需点击“复位”恢复。
|
||||
- ⑨⑩ 运行中“返回”无效(需先停止);调试维护页常显红色警告。
|
||||
|
||||
## 通信(UDP 收包 / 发包)
|
||||
|
||||
通信层位于 `comm/udpcommunication.cpp`,协议为 **JSON 文本**(`QJsonDocument`):
|
||||
|
||||
- 遥控端绑定本地端口 `9000`,向 `127.0.0.1:9001` 发包;
|
||||
- 内置模拟车载端 `comm/mockvehicle.cpp` 绑定 `9001`,向 `9000` 回传遥测,并对命令作出响应。
|
||||
|
||||
上行命令(UI→车载端,`{"t":...}`):`chassis_move` `arm_move` `arm_return` `arm_pause`
|
||||
`gas_start` `gas_stop` `wash_start` `wash_stop` `ball_valve` `pump_power` `pump_rpm`
|
||||
`set_param` `selfcheck_start` `estop` `estop_reset`。
|
||||
|
||||
下行遥测(车载端→UI):`heartbeat` `chassis` `arm` `wash` `tank` `gas` `valve` `pump`
|
||||
`estop` `selfcheck` `selfcheck_done`。
|
||||
|
||||
可在 `config.ini`(程序目录)中配置 `net/local_port`、`net/remote_host`、`net/remote_port`、
|
||||
`net/mock`(true 启用内置模拟端,false 连接真实车载端)、`net/selfcheck_fault`(自检故障演示)。
|
||||
参数(车速、柱塞泵流量、发泡倍数、泡沫比例、空压机流量)与密码经 `QSettings` 持久化,上电自动读取。
|
||||
|
||||
## 目录结构
|
||||
|
||||
- `app/` 全局常量、配色、应用上下文(AppContext)、QSS 样式、闪烁工具
|
||||
- `comm/` UDP 通信层 + 内置模拟车载端
|
||||
- `widgets/` 公共组件:TitleBar / StatusStrip / LedIndicator / NumPadDialog /
|
||||
ConfirmDialog / AlarmBanner / ParamControl / DataCard / FaultTable
|
||||
- `pages/` 各界面(继承 BasePage)
|
||||
@@ -0,0 +1,147 @@
|
||||
#include "appcontext.h"
|
||||
#include "udpcommunication.h"
|
||||
#include "mockvehicle.h"
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
|
||||
AppContext* AppContext::instance()
|
||||
{
|
||||
static AppContext* s = nullptr;
|
||||
if (!s) s = new AppContext();
|
||||
return s;
|
||||
}
|
||||
|
||||
AppContext::AppContext(QObject* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
// 参数与密码持久化:QSettings 写入程序目录 config.ini
|
||||
m_settings = new QSettings(QApplication::applicationDirPath() + "/config.ini",
|
||||
QSettings::IniFormat, this);
|
||||
|
||||
// 首次运行写入默认值
|
||||
if (!m_settings->contains(keySpeed())) m_settings->setValue(keySpeed(), 4.5);
|
||||
if (!m_settings->contains(keyPumpFlow())) m_settings->setValue(keyPumpFlow(), 20);
|
||||
if (!m_settings->contains(keyFoamRatio())) m_settings->setValue(keyFoamRatio(), 6);
|
||||
if (!m_settings->contains(keyFoamPercent()))m_settings->setValue(keyFoamPercent(), 3);
|
||||
if (!m_settings->contains(keyAirFlow())) m_settings->setValue(keyAirFlow(), 100);
|
||||
if (!m_settings->contains("param/pwd")) m_settings->setValue("param/pwd", "6789");
|
||||
if (!m_settings->contains("param/admin_pwd"))m_settings->setValue("param/admin_pwd", "6789");
|
||||
|
||||
// 通信层(UDP 收包发包)
|
||||
m_comm = new UdpCommunication(&telemetry, this);
|
||||
|
||||
// 内置模拟车载端(离线演示:回环 UDP 收发)
|
||||
m_vehicle = new MockVehicle(this);
|
||||
|
||||
// 通信层故障信号 → 写入故障历史
|
||||
connect(m_comm, &UdpCommunication::faultAppended,
|
||||
this, &AppContext::appendFault);
|
||||
|
||||
seedFaultHistory();
|
||||
}
|
||||
|
||||
void AppContext::seedFaultHistory()
|
||||
{
|
||||
// 演示用历史故障汇总(协议示例数据 + 补充)
|
||||
struct Seed { const char* t; const char* sys; const char* code; const char* d; };
|
||||
const Seed seeds[] = {
|
||||
{"2026-05-16 10:08", "机器人底盘", "C01", "底盘电量低"},
|
||||
{"2026-05-16 09:58", "机器人底盘", "C02", "底盘电机温度高"},
|
||||
{"2026-05-16 09:41", "机器人底盘", "C03", "总电压低"},
|
||||
{"2026-05-15 09:08", "机械臂", "A01", "机械臂通信故障"},
|
||||
{"2026-05-15 08:55", "机械臂", "A02", "机械臂自检故障"},
|
||||
{"2026-05-15 08:30", "机械臂", "A03", "关节J2过载"},
|
||||
{"2026-05-14 09:58", "洗消系统", "W01", "柱塞泵故障"},
|
||||
{"2026-05-14 09:20", "洗消系统", "W02", "空压机压力异常"},
|
||||
{"2026-05-14 08:45", "洗消系统", "W03", "电动球阀D1开启故障"},
|
||||
{"2026-05-13 09:08", "洗消系统", "W04", "清水液位低"},
|
||||
{"2026-05-13 08:18", "洗消系统", "W05", "药剂液位低"},
|
||||
{"2026-05-13 08:02", "洗消系统", "W06", "叶片泵故障"},
|
||||
{"2026-05-12 11:20", "气体检测仪", "G01", "检测仪通信故障"},
|
||||
{"2026-05-12 10:50", "气体检测仪", "G02", "有毒物浓度超阈值"},
|
||||
{"2026-05-11 09:30", "气体检测仪", "G03", "主机标定异常"},
|
||||
{"2026-05-11 09:10", "机器人底盘", "C04", "手刹失效"},
|
||||
{"2026-05-10 08:40", "机械臂", "A04", "末端速度超限"},
|
||||
{"2026-05-10 08:15", "气体检测仪", "G04", "传感器信号异常"},
|
||||
};
|
||||
for (const Seed& s : seeds) {
|
||||
FaultRecord r;
|
||||
r.time = QString::fromUtf8(s.t);
|
||||
r.system = QString::fromUtf8(s.sys);
|
||||
r.code = QString::fromUtf8(s.code);
|
||||
r.desc = QString::fromUtf8(s.d);
|
||||
faultHistory.append(r); // 种子数据按“最新在前”顺序直接追加
|
||||
}
|
||||
}
|
||||
|
||||
void AppContext::appendFault(const QString& system, const QString& code, const QString& desc)
|
||||
{
|
||||
FaultRecord r;
|
||||
r.time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm");
|
||||
r.system = system;
|
||||
r.code = code;
|
||||
r.desc = desc;
|
||||
faultHistory.prepend(r); // 最新在前
|
||||
}
|
||||
|
||||
double AppContext::getDouble(const QString& key, double def) const
|
||||
{
|
||||
return m_settings->value(key, def).toDouble();
|
||||
}
|
||||
|
||||
void AppContext::setDouble(const QString& key, double val)
|
||||
{
|
||||
m_settings->setValue(key, val);
|
||||
m_settings->sync();
|
||||
}
|
||||
|
||||
QString AppContext::getString(const QString& key, const QString& def) const
|
||||
{
|
||||
return m_settings->value(key, def).toString();
|
||||
}
|
||||
|
||||
void AppContext::setString(const QString& key, const QString& val)
|
||||
{
|
||||
m_settings->setValue(key, val);
|
||||
m_settings->sync();
|
||||
}
|
||||
|
||||
QString AppContext::password() const
|
||||
{
|
||||
return m_settings->value("param/pwd", "6789").toString();
|
||||
}
|
||||
|
||||
void AppContext::setPassword(const QString& pwd)
|
||||
{
|
||||
m_settings->setValue("param/pwd", pwd);
|
||||
m_settings->sync();
|
||||
}
|
||||
|
||||
QString AppContext::adminPassword() const
|
||||
{
|
||||
return m_settings->value("param/admin_pwd", "6789").toString();
|
||||
}
|
||||
|
||||
void AppContext::resetEstop()
|
||||
{
|
||||
estopTriggered = false;
|
||||
telemetry.estop = false;
|
||||
emit estopChanged(false);
|
||||
// 通知车载端复位
|
||||
if (m_comm) m_comm->sendEstopReset();
|
||||
}
|
||||
|
||||
void AppContext::triggerEstop()
|
||||
{
|
||||
estopTriggered = true;
|
||||
telemetry.estop = true;
|
||||
emit estopChanged(true);
|
||||
if (m_comm) m_comm->sendEstop();
|
||||
}
|
||||
|
||||
void AppContext::setMode(Mode m)
|
||||
{
|
||||
if (mode == m) return;
|
||||
mode = m;
|
||||
emit modeChanged(m);
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
#ifndef APPCONTEXT_H
|
||||
#define APPCONTEXT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QSettings>
|
||||
#include <QVector>
|
||||
#include "global.h"
|
||||
|
||||
class UdpCommunication;
|
||||
class MockVehicle;
|
||||
|
||||
// 故障历史记录
|
||||
struct FaultRecord {
|
||||
QString time; // "2026-05-16 10:08"
|
||||
QString system; // 机器人底盘 / 机械臂 / 洗消系统 / 气体检测仪
|
||||
QString code; // 故障代码
|
||||
QString desc; // 故障名称
|
||||
};
|
||||
|
||||
// ===================== 应用上下文(单例) =====================
|
||||
// 持有:通信层、参数存储、全局状态(模式/急停/通信状态)、遥测数据快照
|
||||
class AppContext : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static AppContext* instance();
|
||||
|
||||
UdpCommunication* comm() const { return m_comm; }
|
||||
MockVehicle* vehicle() const { return m_vehicle; }
|
||||
|
||||
// 遥测数据快照(由通信层填充)
|
||||
Telemetry telemetry;
|
||||
|
||||
// 全局状态
|
||||
Mode mode = Mode::Drive; // 行车/机械臂模式(机械旋钮)
|
||||
bool estopTriggered = false; // 急停是否触发(需人工复位)
|
||||
bool washRunning = false; // 洗消运行中(消除/消毒共用)
|
||||
bool gasRunning = false; // 气体检测仪检测中
|
||||
|
||||
// ===================== 存储区参数(QSettings 持久化) =====================
|
||||
double getDouble(const QString& key, double def) const;
|
||||
void setDouble(const QString& key, double val);
|
||||
QString getString(const QString& key, const QString& def) const;
|
||||
void setString(const QString& key, const QString& val);
|
||||
|
||||
// 密码
|
||||
QString password() const;
|
||||
void setPassword(const QString& pwd);
|
||||
QString adminPassword() const;
|
||||
|
||||
// 洗消/底盘参数出厂值与键名
|
||||
static QString keySpeed() { return "param/speed"; } // 车速 km/h,出厂 4.5
|
||||
static QString keyPumpFlow() { return "param/pump_flow"; } // 柱塞泵流量,出厂 20
|
||||
static QString keyFoamRatio() { return "param/foam_ratio"; } // 发泡倍数,出厂 6
|
||||
static QString keyFoamPercent(){ return "param/foam_percent"; }// 泡沫比例,出厂 3
|
||||
static QString keyAirFlow() { return "param/air_flow"; } // 空压机流量,出厂 100
|
||||
|
||||
// 故障历史(⑫故障查询数据源)
|
||||
QVector<FaultRecord> faultHistory;
|
||||
void appendFault(const QString& system, const QString& code, const QString& desc);
|
||||
|
||||
// 急停复位(人工复位)
|
||||
void resetEstop();
|
||||
|
||||
// 触发急停(软急停/物理急停统一入口)
|
||||
void triggerEstop();
|
||||
|
||||
// 模式切换(行车/机械臂,由面板机械旋钮或演示按钮触发)
|
||||
void setMode(Mode m);
|
||||
|
||||
signals:
|
||||
void modeChanged(Mode m);
|
||||
void estopChanged(bool triggered);
|
||||
void commChanged(bool ok);
|
||||
|
||||
private:
|
||||
explicit AppContext(QObject* parent = nullptr);
|
||||
void seedFaultHistory();
|
||||
QSettings* m_settings = nullptr;
|
||||
UdpCommunication* m_comm = nullptr;
|
||||
MockVehicle* m_vehicle = nullptr;
|
||||
};
|
||||
|
||||
// 便捷访问宏
|
||||
#define CTX AppContext::instance()
|
||||
|
||||
#endif // APPCONTEXT_H
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
#include "global.h"
|
||||
#include <QStyle>
|
||||
|
||||
// 启动 500ms 闪烁:每 500ms 切换一次动态属性,QSS 据此在 40%↔100% 透明度间切换
|
||||
QTimer* startBlink(QWidget* w, const char* prop)
|
||||
{
|
||||
// 复用已存在的定时器
|
||||
if (auto* t = w->findChild<QTimer*>(QString("blink_") + prop))
|
||||
return t;
|
||||
QTimer* t = new QTimer(w);
|
||||
t->setObjectName(QString("blink_") + prop);
|
||||
t->setInterval(500);
|
||||
QObject::connect(t, &QTimer::timeout, w, [w, prop]() {
|
||||
bool cur = w->property(prop).toBool();
|
||||
w->setProperty(prop, !cur);
|
||||
w->style()->unpolish(w);
|
||||
w->style()->polish(w);
|
||||
w->update();
|
||||
});
|
||||
w->setProperty(prop, true);
|
||||
t->start();
|
||||
return t;
|
||||
}
|
||||
|
||||
void stopBlink(QWidget* w, const char* prop)
|
||||
{
|
||||
if (auto* t = w->findChild<QTimer*>(QString("blink_") + prop)) {
|
||||
t->stop();
|
||||
delete t;
|
||||
}
|
||||
w->setProperty(prop, false);
|
||||
w->style()->unpolish(w);
|
||||
w->style()->polish(w);
|
||||
w->update();
|
||||
}
|
||||
|
||||
QString appStyleSheet()
|
||||
{
|
||||
const QString s = QString(R"QSS(
|
||||
* {
|
||||
font-family: "Microsoft YaHei", "PingFang SC", "Source Han Sans CN";
|
||||
outline: none;
|
||||
}
|
||||
QWidget {
|
||||
background-color: BG;
|
||||
color: TXT;
|
||||
}
|
||||
QWidget#pageRoot {
|
||||
background-color: BG;
|
||||
}
|
||||
QLabel {
|
||||
background: transparent;
|
||||
color: TXT;
|
||||
}
|
||||
QLabel[sub="true"] { color: SUB; }
|
||||
QLabel[title="true"] { color: TXT; font-weight: 700; }
|
||||
|
||||
/* ===== 按钮 ===== */
|
||||
QPushButton {
|
||||
background-color: PHI;
|
||||
color: TXT;
|
||||
border: 1px solid BD;
|
||||
border-radius: 12px;
|
||||
font-size: 22px;
|
||||
min-height: 56px;
|
||||
}
|
||||
QPushButton:hover { background-color: PRI; color: TXT; border-color: PRI; }
|
||||
QPushButton:pressed { background-color: PRI; color: #FFFFFF; border-color: PRI; }
|
||||
QPushButton:checked { background-color: PRI; color: #FFFFFF; border: none; }
|
||||
QPushButton:disabled { background-color: DIS; color: DIST; border-color: DIS; }
|
||||
|
||||
QPushButton[variant="primary"] { background-color: PRI; color: #FFFFFF; border: none; }
|
||||
QPushButton[variant="primary"]:disabled { background-color: DIS; color: DIST; }
|
||||
QPushButton[variant="danger"] { background-color: DAN; color: #FFFFFF; border: 1px solid DAN; border-radius: 6px; }
|
||||
QPushButton[variant="danger"]:disabled { background-color: DIS; color: DIST; border-color: DIS; }
|
||||
QPushButton[variant="link"] { background: transparent; color: PRI; border: none; font-size: 22px; }
|
||||
QPushButton[variant="estop"] {
|
||||
background-color: DAN; color: #FFFFFF; border: 1px solid DAN; border-radius: 6px; font-size: 24px; font-weight: 700;
|
||||
}
|
||||
|
||||
/* ===== 输入框 ===== */
|
||||
QLineEdit {
|
||||
background-color: BG;
|
||||
border: 2px solid BD;
|
||||
border-radius: 8px;
|
||||
color: TXT;
|
||||
font-size: 32px;
|
||||
padding: 0 12px;
|
||||
}
|
||||
QLineEdit:focus { border: 3px solid PRI; }
|
||||
|
||||
/* ===== 进度条 ===== */
|
||||
QProgressBar {
|
||||
background-color: PHI;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
color: #FFFFFF;
|
||||
font-size: 22px;
|
||||
}
|
||||
QProgressBar::chunk { background-color: PRI; border-radius: 4px; }
|
||||
|
||||
/* ===== 表格 ===== */
|
||||
QTableWidget {
|
||||
background-color: PAN;
|
||||
color: TXT;
|
||||
border: 1px solid BD;
|
||||
gridline-color: BD;
|
||||
font-size: 22px;
|
||||
alternate-background-color: #2A3442;
|
||||
}
|
||||
QHeaderView::section {
|
||||
background-color: PHI;
|
||||
color: TXT;
|
||||
border: none;
|
||||
border-right: 1px solid BD;
|
||||
border-bottom: 1px solid BD;
|
||||
padding: 8px;
|
||||
font-size: 22px;
|
||||
}
|
||||
QTableWidget::item { padding: 6px; }
|
||||
QTableWidget::item:selected { background-color: rgba(61,139,253,0.15); color: TXT; }
|
||||
|
||||
/* ===== 数字键盘 ===== */
|
||||
QPushButton[numpad="true"] {
|
||||
background-color: PHI; color: TXT; border: 1px solid BD; border-radius: 12px; font-size: 40px;
|
||||
}
|
||||
QPushButton[numpad="true"]:pressed { background-color: PRI; color: #FFFFFF; }
|
||||
|
||||
/* ===== 告警文字(红色闪烁由 blink 属性驱动) ===== */
|
||||
QLabel[alert="true"] { color: DAN; font-weight: 700; }
|
||||
QLabel[alert="true"][blink="false"] { color: rgba(229,72,77,102); }
|
||||
QLabel[amber="true"] { color: WAR; font-weight: 700; }
|
||||
|
||||
/* ===== 数据卡片 ===== */
|
||||
QWidget[card="true"] {
|
||||
background-color: PAN;
|
||||
border: 2px solid BD;
|
||||
border-radius: 12px;
|
||||
}
|
||||
QLabel[cardTitle="true"] { color: TXT; font-weight: 700; }
|
||||
)QSS");
|
||||
|
||||
// 用占位替换(注意:DIST 须在 DIS 之前替换,避免前缀误匹配)
|
||||
QString out = s;
|
||||
out.replace("DIST", C::DISABLED_T);
|
||||
out.replace("DIS", C::DISABLED);
|
||||
out.replace("BG", C::BG);
|
||||
out.replace("PAN", C::PANEL);
|
||||
out.replace("PHI", C::PANEL_HI);
|
||||
out.replace("BD", C::BORDER);
|
||||
out.replace("TXT", C::TEXT);
|
||||
out.replace("SUB", C::TEXT_SUB);
|
||||
out.replace("PRI", C::PRIMARY);
|
||||
out.replace("SUC", C::SUCCESS);
|
||||
out.replace("WAR", C::WARNING);
|
||||
out.replace("DAN", C::DANGER);
|
||||
return out;
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
#ifndef GLOBAL_H
|
||||
#define GLOBAL_H
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QVector>
|
||||
#include <QWidget>
|
||||
#include <QTimer>
|
||||
#include <QVariant>
|
||||
|
||||
// ===================== 画布与全局常量 =====================
|
||||
// 屏幕分辨率(1920×1080 横屏);若部署在更低分辨率屏,可按同一比例整体缩放
|
||||
static const int SCREEN_W = 1920;
|
||||
static const int SCREEN_H = 1080;
|
||||
|
||||
// ===================== 工业风格配色体系(QSS 十六进制) =====================
|
||||
namespace C {
|
||||
const QString BG = "#161C23"; // 主背景:窗口画布底色
|
||||
const QString PANEL = "#242E3A"; // 面板背景:卡片/弹窗/顶条/底条
|
||||
const QString PANEL_HI = "#2D3947"; // 面板亮色:按钮常态、表头、进度条底
|
||||
const QString BORDER = "#3D4A59"; // 分割线:边框、表格线
|
||||
const QString TEXT = "#E6EDF3"; // 主文字:标题、正文、数值
|
||||
const QString TEXT_SUB = "#9AA7B4"; // 次文字:说明、单位、标签
|
||||
const QString PRIMARY = "#3D8BFD"; // 强调主色:主按钮、选中、焦点、进度条
|
||||
const QString SUCCESS = "#36C75A"; // 成功/运行:运行、开启、到位
|
||||
const QString WARNING = "#F5A623"; // 警告:提醒、待确认
|
||||
const QString DANGER = "#E5484D"; // 危险/故障:急停、故障、警示
|
||||
const QString DISABLED = "#56636F"; // 禁用:不可操作控件底色
|
||||
const QString DISABLED_T = "#6B7A88"; // 禁用文字
|
||||
}
|
||||
|
||||
// ===================== 操作模式 =====================
|
||||
// 面板机械旋钮切换:行车模式 / 机械臂模式
|
||||
enum class Mode { Drive = 0, Arm = 1 };
|
||||
|
||||
// ===================== 页面枚举(QStackedWidget 索引) =====================
|
||||
enum PageId {
|
||||
PageBoot = 0, // ③ 开机密码
|
||||
PageWarning, // 密码警告
|
||||
PageMgmtLogin, // 密码管理登录
|
||||
PageMgmt, // 密码管理
|
||||
PageReset, // 密码重置
|
||||
PageSelfCheck, // ④ 自检
|
||||
PageJob, // ⑤ 作业选择
|
||||
PageChassis, // ⑥ 机器人底盘
|
||||
PageArm, // ⑦ 机械臂
|
||||
PageGas, // ⑧ 气体检测仪
|
||||
PageClean, // ⑨ 手动消除
|
||||
PageDisinfect, // ⑩ 手动消毒
|
||||
PageDebug, // ⑪ 调试维护
|
||||
PageFault, // ⑫ 故障查询
|
||||
PageCount
|
||||
};
|
||||
|
||||
// ===================== 遥测数据(车载端 → UI) =====================
|
||||
// 由通信层解析 UDP 报文后填充,页面 500ms 定时读取刷新
|
||||
struct Telemetry {
|
||||
// 底盘
|
||||
int soc = 85; // 电量 %
|
||||
double volt = 360.0; // 电压 V
|
||||
double speed = 3.45; // 车速 km/h
|
||||
bool handbrake = true; // 手刹
|
||||
QStringList chassisFaults; // 底盘故障(多条 2s 轮换)
|
||||
|
||||
// 机械臂
|
||||
QVector<double> js{30, 20, 0, 90, 45, 0}; // 关节角 J1~J6(°)
|
||||
QString pos = "--"; // 末端位置 XYZ
|
||||
QString pose = "--"; // 姿态 RX/RY/RZ
|
||||
double vel = 0.0; // 末端速度
|
||||
QString returnState = "idle";// 回位状态 idle/returning/done/fault
|
||||
bool armHomed = false; // 是否已回位(用于底盘“机械臂未回位”告警)
|
||||
|
||||
// 洗消
|
||||
QString washMode = "--"; // 手动消除 / 手动消毒
|
||||
double flowA = 0.0; // A 药剂流量 L/min
|
||||
double flowB = 0.0; // B 药剂流量 L/min
|
||||
double gasFlow = 0.0; // 气体流量 L/min
|
||||
double press = 0.0; // 管路压力 MPa
|
||||
double airPress = 0.0; // 空压机压力 MPa
|
||||
double foam = 0.0; // 发泡倍数
|
||||
QStringList washFaults; // 洗消故障代码
|
||||
|
||||
// 液位
|
||||
double levelA = 100.0; // 清水/药剂液位 L
|
||||
double levelFoam = 30.0; // 泡沫液位 L
|
||||
|
||||
// 气体检测仪
|
||||
QString gasHost = "standby"; // 主机状态 standby/detecting/fault
|
||||
QString gasType = "--"; // 有毒物种类
|
||||
QString gasLevel = "--"; // 有毒物等级
|
||||
double gasConc = 0.0; // 有毒物浓度 ppb
|
||||
|
||||
// 球阀 D1/D2
|
||||
bool d1open = false; // D1 开启到位
|
||||
bool d1close = true; // D1 关闭到位
|
||||
bool d2open = false; // D2 开启到位
|
||||
bool d2close = true; // D2 关闭到位
|
||||
QString valveFault; // 球阀故障码
|
||||
|
||||
// 泵
|
||||
bool plunger = false; // 柱塞泵上电
|
||||
bool air = false; // 空压机上电
|
||||
bool leaf = false; // 叶片泵上电
|
||||
QStringList pumpFaults; // 泵故障代码
|
||||
|
||||
// 全局
|
||||
bool commOk = true; // 通信状态
|
||||
bool estop = false; // 急停触发
|
||||
};
|
||||
|
||||
// ===================== 工具函数 =====================
|
||||
// 启动 500ms 闪烁:每 500ms 切换一次 QSS 动态属性(40% ↔ 100% 透明度由 QSS 规则体现)
|
||||
QTimer* startBlink(QWidget* w, const char* prop = "blink");
|
||||
|
||||
// 关闭闪烁定时器并复位属性
|
||||
void stopBlink(QWidget* w, const char* prop = "blink");
|
||||
|
||||
// 全局 QSS 样式表
|
||||
QString appStyleSheet();
|
||||
|
||||
#endif // GLOBAL_H
|
||||
@@ -0,0 +1,21 @@
|
||||
QMAKE_CXX.QT_COMPILER_STDCXX = 201402L
|
||||
QMAKE_CXX.QMAKE_GCC_MAJOR_VERSION = 8
|
||||
QMAKE_CXX.QMAKE_GCC_MINOR_VERSION = 1
|
||||
QMAKE_CXX.QMAKE_GCC_PATCH_VERSION = 0
|
||||
QMAKE_CXX.COMPILER_MACROS = \
|
||||
QT_COMPILER_STDCXX \
|
||||
QMAKE_GCC_MAJOR_VERSION \
|
||||
QMAKE_GCC_MINOR_VERSION \
|
||||
QMAKE_GCC_PATCH_VERSION
|
||||
QMAKE_CXX.INCDIRS = \
|
||||
F:/QT/Tools/mingw810_32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++ \
|
||||
F:/QT/Tools/mingw810_32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/i686-w64-mingw32 \
|
||||
F:/QT/Tools/mingw810_32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/backward \
|
||||
F:/QT/Tools/mingw810_32/lib/gcc/i686-w64-mingw32/8.1.0/include \
|
||||
F:/QT/Tools/mingw810_32/lib/gcc/i686-w64-mingw32/8.1.0/include-fixed \
|
||||
F:/QT/Tools/mingw810_32/i686-w64-mingw32/include
|
||||
QMAKE_CXX.LIBDIRS = \
|
||||
F:/QT/Tools/mingw810_32/lib/gcc/i686-w64-mingw32/8.1.0 \
|
||||
F:/QT/Tools/mingw810_32/lib/gcc \
|
||||
F:/QT/Tools/mingw810_32/i686-w64-mingw32/lib \
|
||||
F:/QT/Tools/mingw810_32/lib
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user