2026-06-26 17:55:15 +08:00
|
|
|
|
#include <QApplication>
|
|
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
|
#include <QDir>
|
|
|
|
|
|
#include <QStandardPaths>
|
|
|
|
|
|
#include <QFileInfo>
|
|
|
|
|
|
#include <QIcon>
|
2026-06-29 13:59:12 +08:00
|
|
|
|
#include <QMetaType>
|
2026-06-26 17:55:15 +08:00
|
|
|
|
|
|
|
|
|
|
#include "mainwindow.h"
|
|
|
|
|
|
#include "Presenter/Inc/ConfigManager.h"
|
|
|
|
|
|
#include "Version.h"
|
|
|
|
|
|
#include "SingleInstanceManager.h"
|
|
|
|
|
|
|
|
|
|
|
|
// FFmpeg-rockchip 内部符号的 stub 定义(链接时需要但本进程不会真正调用)
|
|
|
|
|
|
#ifdef __linux__
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
|
// rkmppdec.c 需要,但本进程只拉流解码,不用 encoder
|
|
|
|
|
|
typedef int MppCodingType;
|
|
|
|
|
|
const char* querystring(MppCodingType /*coding*/) { return "unknown"; }
|
|
|
|
|
|
// libavutil 可能在未被直接引用时缺失
|
|
|
|
|
|
unsigned int ff_log_level = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
|
|
QString resolveConfigPath()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 1) exe 同目录下的 config/config.xml
|
|
|
|
|
|
QDir d(QCoreApplication::applicationDirPath());
|
|
|
|
|
|
QString p = d.absoluteFilePath("config/config.xml");
|
|
|
|
|
|
if (QFileInfo::exists(p)) return p;
|
|
|
|
|
|
|
|
|
|
|
|
// 2) 工作目录
|
|
|
|
|
|
p = QDir::current().absoluteFilePath("config/config.xml");
|
|
|
|
|
|
if (QFileInfo::exists(p)) return p;
|
|
|
|
|
|
|
|
|
|
|
|
// 3) AppData (Windows) / 用户目录 (Linux)
|
|
|
|
|
|
QString dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
|
|
|
|
|
QDir().mkpath(dataDir + "/DroneScrewCtrl");
|
|
|
|
|
|
return dataDir + "/DroneScrewCtrl/config.xml";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char* argv[])
|
|
|
|
|
|
{
|
|
|
|
|
|
QApplication a(argc, argv);
|
|
|
|
|
|
a.setApplicationName(DRONESCREWCTRL_APP_NAME);
|
|
|
|
|
|
a.setApplicationVersion(DRONESCREWCTRL_VERSION_STRING);
|
|
|
|
|
|
a.setWindowIcon(QIcon(":/dronescrewctrl/resource/logo.png"));
|
2026-06-29 13:59:12 +08:00
|
|
|
|
a.setStyleSheet(QStringLiteral(
|
|
|
|
|
|
"QMessageBox { background-color: rgb(25, 26, 28); color: rgb(221, 225, 233); }"
|
|
|
|
|
|
"QMessageBox QLabel { color: rgb(221, 225, 233); background-color: transparent; }"
|
|
|
|
|
|
"QMessageBox QPushButton { background-color: rgb(47, 48, 52); color: rgb(221, 225, 233); border: 1px solid rgb(75, 78, 86); padding: 5px 16px; }"
|
|
|
|
|
|
"QMessageBox QPushButton:hover { background-color: rgb(58, 60, 66); }"));
|
|
|
|
|
|
qRegisterMetaType<CtrlDetectionFrame>("CtrlDetectionFrame");
|
2026-06-26 17:55:15 +08:00
|
|
|
|
|
|
|
|
|
|
// 单实例检查(使用标准 SingleInstanceManager,确保退出时正确释放)
|
|
|
|
|
|
SingleInstanceManager instanceMgr("DroneScrewCtrlApp");
|
|
|
|
|
|
if (instanceMgr.isAnotherInstanceRunning())
|
|
|
|
|
|
{
|
|
|
|
|
|
QMessageBox::information(nullptr,
|
|
|
|
|
|
QObject::tr("应用程序已运行"),
|
|
|
|
|
|
QObject::tr("无人机螺杆控制端已经在运行中,请勿重复启动!"),
|
|
|
|
|
|
QMessageBox::Ok);
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString configPath = resolveConfigPath();
|
|
|
|
|
|
ConfigManager::Instance().Initialize(configPath.toStdString());
|
|
|
|
|
|
|
|
|
|
|
|
MainWindow w;
|
|
|
|
|
|
w.show();
|
|
|
|
|
|
return a.exec();
|
|
|
|
|
|
}
|