fix: 修复启动白屏与地图崩溃问题

- SetUseOpenGL(false): QGLWidget 在当前系统不兼容,改用软件渲染
- ExtensionHost_v2: 添加 contributionRegistry() getter 修复空指针
- main.cpp: 两阶段启动 (show → QTimer::singleShot → initialize)
- mainwindow: 分离构造函数与 initialize(),结尾调用 onTabIndexChanged(3)
- 修复 Qt DLL 部署:使用 windeployqt 确保运行时库版本匹配
This commit is contained in:
2026-06-02 19:01:24 +08:00
parent 94fcdb12e0
commit 61cd75cd56
39 changed files with 2994 additions and 1258 deletions
+3 -3
View File
@@ -1,10 +1,10 @@
# PluginSDK — 插件开发工具包(静态库)
# 包含:IPluginPluginContextServiceRegistryMavLinkServicePluginManifest
# PluginSDK â€? æ’ä»¶å¼?å‘å·¥å…·åŒ…ï¼ˆé™æ€åº“ï¼?
# 包å«ï¼šIPluginã€PluginContextã€ServiceRegistryã€MavLinkServiceã€PluginManifest
add_library(PluginSDK STATIC
PluginContext.cpp
ServiceRegistry.cpp
MavLinkService.cpp
MavLinkServiceBridge.cpp
Logging.cpp
${CMAKE_SOURCE_DIR}/App/Plugins/PluginManifest.cpp
)
+13 -2
View File
@@ -9,8 +9,8 @@
#include "mavlink_types.h"
// ============================================================
// 服务接口体系(纯虚接口,不继承QObject,避免菱形继承)
// 插件通过 ServiceRegistry 发现服务
// 服务接口体系(纯虚接口,不继承QObject,避免菱形继承)
// 插件通过 ServiceRegistry 发现服务
// ============================================================
class IDataProvider
@@ -18,6 +18,10 @@ class IDataProvider
public:
virtual ~IDataProvider() = default;
virtual QString serviceId() const = 0;
virtual void requestSystemStatus() = 0;
virtual void requestAllParams() = 0;
virtual void setUpdateInterval(int ms) = 0;
virtual void enableDataStream(bool enabled) = 0;
};
class ILinkProvider
@@ -25,6 +29,10 @@ class ILinkProvider
public:
virtual ~ILinkProvider() = default;
virtual QString serviceId() const = 0;
virtual void connectToVehicle(const QString &port, int baudRate) = 0;
virtual void disconnectFromVehicle() = 0;
virtual bool isLinkConnected() const = 0;
virtual QStringList availablePorts() const = 0;
};
class ICommandProvider
@@ -80,6 +88,9 @@ class ISensorProvider
public:
virtual ~ISensorProvider() = default;
virtual QString serviceId() const = 0;
virtual void enableSensorStream(const QString &sensorName, bool enabled) = 0;
virtual void requestSensorCalibration() = 0;
virtual QVariantMap getSensorHealth() const = 0;
};
class IRCProvider
+13
View File
@@ -0,0 +1,13 @@
#include "Logging.h"
// 日志分类定义(每个分类一行,在 .cpp 中定义以遵守 ODR)
Q_LOGGING_CATEGORY(gcs_comm, "gcs.comm")
Q_LOGGING_CATEGORY(gcs_mavlink, "gcs.mavlink")
Q_LOGGING_CATEGORY(gcs_mission, "gcs.mission")
Q_LOGGING_CATEGORY(gcs_command, "gcs.command")
Q_LOGGING_CATEGORY(gcs_param, "gcs.param")
Q_LOGGING_CATEGORY(gcs_vehicle, "gcs.vehicle")
Q_LOGGING_CATEGORY(gcs_ui, "gcs.ui")
Q_LOGGING_CATEGORY(gcs_map, "gcs.map")
Q_LOGGING_CATEGORY(gcs_datalog, "gcs.datalog")
Q_LOGGING_CATEGORY(gcs_app, "gcs.app")
+50
View File
@@ -0,0 +1,50 @@
#ifndef GCS_LOGGING_H
#define GCS_LOGGING_H
#include <QLoggingCategory>
// ============================================================
// GCS 统一日志分类系统
//
// 替代散落的 qDebug()/qWarning() 裸调用,
// 支持运行时通过 QT_LOGGING_RULES 环境变量按模块过滤日志。
//
// 用法:
// qCDebug(gcs_comm) << "Serial port opened:" << portName;
// qCWarning(gcs_mavlink) << "Checksum mismatch, msgid:" << msg.msgid;
//
// 运行时控制示例:
// QT_LOGGING_RULES="gcs.comm.debug=true;gcs.mavlink.info=true"
// ============================================================
// 通讯层:串口/UDP/组播连接、收发统计
Q_DECLARE_LOGGING_CATEGORY(gcs_comm)
// MAVLink 协议层:解析、编解码、帧校验
Q_DECLARE_LOGGING_CATEGORY(gcs_mavlink)
// 任务/航线:上传、下载、航点处理
Q_DECLARE_LOGGING_CATEGORY(gcs_mission)
// 指令:指令下发、ACK 处理
Q_DECLARE_LOGGING_CATEGORY(gcs_command)
// 参数:参数读写、同步
Q_DECLARE_LOGGING_CATEGORY(gcs_param)
// 飞控数据:传感器、姿态、GPS 数据
Q_DECLARE_LOGGING_CATEGORY(gcs_vehicle)
// UI 界面:面板切换、用户操作
Q_DECLARE_LOGGING_CATEGORY(gcs_ui)
// 地图:瓦片加载、航点编辑
Q_DECLARE_LOGGING_CATEGORY(gcs_map)
// 数据记录:CSV/TLOG 文件 I/O
Q_DECLARE_LOGGING_CATEGORY(gcs_datalog)
// 通用/启动/配置
Q_DECLARE_LOGGING_CATEGORY(gcs_app)
#endif // GCS_LOGGING_H
+212 -144
View File
@@ -1,144 +1,212 @@
#include "MavLinkServiceBridge.h"
#include "dlink.h"
#include "mavlinknode.h"
MavLinkServiceBridge::MavLinkServiceBridge(DLink *dlink, QObject *parent)
: QObject(parent)
, m_dlink(dlink)
{
}
void MavLinkServiceBridge::wireFromMavLinkNode()
{
if (!m_dlink || !m_dlink->mavlinknode) return;
MavLinkNode *node = m_dlink->mavlinknode;
connect(node, &MavLinkNode::CommuniationLost, this, &MavLinkServiceBridge::commLost);
connect(node, &MavLinkNode::beep, this, &MavLinkServiceBridge::beepRequested);
connect(node, &MavLinkNode::updateDlink, this, &MavLinkServiceBridge::dlinkStatsChanged);
if (node->Commander) {
connect(node->Commander, &commandprocess::commandAccepted,
this, &MavLinkServiceBridge::commandResult);
}
if (node->Mission) {
connect(node->Mission, &MissionProcess::clearWaypoint,
this, &MavLinkServiceBridge::waypointCleared);
connect(node->Mission, &MissionProcess::sendItemOK,
this, &MavLinkServiceBridge::waypointSendOk);
connect(node->Mission, &MissionProcess::currentPoint,
this, &MavLinkServiceBridge::waypointCurrent);
}
connect(node, &MavLinkNode::addVehicles, this, &MavLinkServiceBridge::vehicleListChanged);
if (node->replay) {
connect(node->replay, &Replay::currentPercentage,
this, &MavLinkServiceBridge::replayProgressChanged);
connect(node->replay, &Replay::replayComplete,
this, &MavLinkServiceBridge::replayEnded);
}
if (node->Terminal) {
connect(node->Terminal, &terminal::Recieve,
this, &MavLinkServiceBridge::terminalOutput);
}
if (node->RC) {
connect(node->RC, &rcprocess::new_remote_ctrl,
this, &MavLinkServiceBridge::rcChannelsUpdated);
}
}
void MavLinkServiceBridge::writeCommandLong(float p1, float p2, float p3, float p4,
float p5, float p6, float p7,
uint16_t cmd, uint8_t confirmation)
{
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Commander)
m_dlink->mavlinknode->Commander->WriteCmd_long(p1, p2, p3, p4, p5, p6, p7, cmd, confirmation);
}
void MavLinkServiceBridge::writeParameter(uint8_t sysid, uint8_t compid,
QVariant parmname, QVariant type, QVariant value)
{
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Parameter)
m_dlink->mavlinknode->Parameter->WriteCmd2(sysid, compid, parmname, type, value);
}
void MavLinkServiceBridge::readWaypoints(uint8_t sysid, uint8_t compid, int count)
{
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Mission)
m_dlink->mavlinknode->Mission->ReadCmd(sysid, compid, count);
}
void MavLinkServiceBridge::writeWaypoints(uint8_t sysid, uint8_t compid, uint32_t total, int current)
{
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Mission)
m_dlink->mavlinknode->Mission->WriteCmd(sysid, compid, total, current);
}
void MavLinkServiceBridge::setCurrentPoint(int point)
{
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Mission)
m_dlink->mavlinknode->Mission->SetCurrentPoint(point);
}
void MavLinkServiceBridge::readAll(uint8_t sysid, uint8_t compid, uint8_t index)
{
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Parameter)
m_dlink->mavlinknode->Parameter->ReadCmd(sysid, compid, index);
}
void MavLinkServiceBridge::writeValue(uint8_t sysid, uint8_t compid,
const char *id, uint8_t type, float value)
{
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Parameter)
m_dlink->mavlinknode->Parameter->WriteCmd(sysid, compid, id, type, value);
}
void MavLinkServiceBridge::startReplay(bool start)
{
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->replay)
m_dlink->mavlinknode->replay->startReplay(start);
}
void MavLinkServiceBridge::setPercentage(float pct)
{
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->replay)
m_dlink->mavlinknode->replay->setPercentage(pct);
}
void MavLinkServiceBridge::setMultiple(double mul)
{
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->replay)
m_dlink->mavlinknode->replay->setMultiple(mul);
}
void MavLinkServiceBridge::transmit(const QString &data)
{
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Terminal)
m_dlink->mavlinknode->Terminal->Transmit(data);
}
void MavLinkServiceBridge::softUpdate(const QList<uint16_t> &channels)
{
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->RC)
m_dlink->mavlinknode->RC->SoftRCUpdate(channels);
}
void MavLinkServiceBridge::setActive(uint32_t mask)
{
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->RC)
m_dlink->mavlinknode->RC->setRCActive(mask);
}
void MavLinkServiceBridge::setLogFile(const QString &path)
{
if (m_dlink && m_dlink->mavlinknode)
m_dlink->mavlinknode->setLogfile(path);
}
void MavLinkServiceBridge::createCSV()
{
if (m_dlink && m_dlink->mavlinknode)
m_dlink->mavlinknode->CreateCSV();
}
#include "MavLinkServiceBridge.h"
#include "dlink.h"
#include "mavlinknode.h"
MavLinkServiceBridge::MavLinkServiceBridge(DLink *dlink, QObject *parent)
: QObject(parent)
, m_dlink(dlink)
{
}
void MavLinkServiceBridge::wireFromMavLinkNode()
{
if (!m_dlink || !m_dlink->mavlinknode) return;
MavLinkNode *node = m_dlink->mavlinknode;
connect(node, &MavLinkNode::CommuniationLost, this, &MavLinkServiceBridge::commLost);
connect(node, &MavLinkNode::beep, this, &MavLinkServiceBridge::beepRequested);
connect(node, &MavLinkNode::updateDlink, this, &MavLinkServiceBridge::dlinkStatsChanged);
if (node->Commander) {
connect(node->Commander, &commandprocess::commandAccepted,
this, &MavLinkServiceBridge::commandResult);
}
if (node->Mission) {
connect(node->Mission, &MissionProcess::clearWaypoint,
this, &MavLinkServiceBridge::waypointCleared);
connect(node->Mission, &MissionProcess::sendItemOK,
this, &MavLinkServiceBridge::waypointSendOk);
connect(node->Mission, &MissionProcess::currentPoint,
this, &MavLinkServiceBridge::waypointCurrent);
}
connect(node, &MavLinkNode::addVehicles, this, &MavLinkServiceBridge::vehicleListChanged);
if (node->replay) {
connect(node->replay, &Replay::currentPercentage,
this, &MavLinkServiceBridge::replayProgressChanged);
connect(node->replay, &Replay::replayComplete,
this, &MavLinkServiceBridge::replayEnded);
}
if (node->Terminal) {
connect(node->Terminal, &terminal::Recieve,
+19
View File
@@ -61,6 +61,23 @@ public:
void setLogFile(const QString &path) override;
void createCSV() override;
// IDataProvider
void requestSystemStatus() override;
void requestAllParams() override;
void setUpdateInterval(int ms) override;
void enableDataStream(bool enabled) override;
// ILinkProvider
void connectToVehicle(const QString &port, int baudRate) override;
void disconnectFromVehicle() override;
bool isLinkConnected() const override;
QStringList availablePorts() const override;
// ISensorProvider
void enableSensorStream(const QString &sensorName, bool enabled) override;
void requestSensorCalibration() override;
QVariantMap getSensorHealth() const override;
signals:
void commLost(bool lost);
void beepRequested(int type);
@@ -83,6 +100,8 @@ signals:
void rawMavlinkMsg(const QByteArray &data);
void rawSensorData(int channel, const QByteArray &data);
void mavlinkMessageReceived(const mavlink_message_t &msg);
public:
DLink *getDLink() const { return m_dlink; }
-2
View File
@@ -35,14 +35,12 @@ public:
template<typename T>
T *get(const QString &serviceId) const
{
static_assert(std::is_base_of_v<IService, T>, "T must derive from IService");
return dynamic_cast<T*>(m_services.value(serviceId, nullptr));
}
template<typename T>
T *get()
{
static_assert(std::is_base_of_v<IService, T>, "T must derive from IService");
for (auto *s : m_services) {
if (auto *t = dynamic_cast<T*>(s)) {
return t;