#include "mainwindow.h" #include "SingleInstanceManager.h" #include "AuthView.h" #include "AuthManager.h" #include "HolePitPositionPresenter.h" #include "IYHolePitPositionStatus.h" #include "VrLog.h" #include #include #include #include #include #include #ifdef Q_OS_UNIX #include #include #endif // 无桌面模式下的状态监听器,将状态信息输出到日志 class HeadlessStatusListener : public IYHolePitPositionStatus { public: void OnStatusUpdate(const std::string& msg) override { LOG_INFO("[Headless] Status: %s\n", msg.c_str()); } void OnDetectionResult(const HolePitPositionResult& result) override { LOG_INFO("[Headless] DetectionResult received, errorCode=%d\n", result.errorCode); } void OnCamera1StatusChanged(bool connected) override { LOG_INFO("[Headless] Camera1: %s\n", connected ? "connected" : "disconnected"); } void OnCamera2StatusChanged(bool connected) override { LOG_INFO("[Headless] Camera2: %s\n", connected ? "connected" : "disconnected"); } void OnRobotConnectionChanged(bool connected) override { LOG_INFO("[Headless] Robot: %s\n", connected ? "connected" : "disconnected"); } void OnSerialConnectionChanged(bool connected) override { LOG_INFO("[Headless] Serial: %s\n", connected ? "connected" : "disconnected"); } void OnCameraCountChanged(int count) override { LOG_INFO("[Headless] CameraCount: %d\n", count); } void OnWorkStatusChanged(WorkStatus status) override { LOG_INFO("[Headless] WorkStatus changed: %d\n", static_cast(status)); } }; #ifdef Q_OS_UNIX // 检测设备文件是否存在 static bool deviceExists(const char* path) { struct stat st; return stat(path, &st) == 0; } // 检测是否有可用的显示设备(X11、Wayland、framebuffer、DRM 任意一种即可) static bool detectDisplay() { // X11 / Wayland 环境变量 const char* display = std::getenv("DISPLAY"); const char* waylandDisp = std::getenv("WAYLAND_DISPLAY"); if ((display && strlen(display) > 0) || (waylandDisp && strlen(waylandDisp) > 0)) { return true; } // Framebuffer(嵌入式 ARM 常见) if (deviceExists("/dev/fb0")) { return true; } return false; } #endif int main(int argc, char *argv[]) { bool hasDisplay = true; #ifdef Q_OS_UNIX hasDisplay = detectDisplay(); if (!hasDisplay) { qputenv("QT_QPA_PLATFORM", "offscreen"); fprintf(stderr, "[Main] No display detected, running in headless mode.\n"); fflush(stderr); } #endif QApplication a(argc, argv); SingleInstanceManager instanceManager("HolePitPositionApp_SingleInstance_Key"); if (hasDisplay) { // ---- 有桌面:完整 UI 模式 ---- a.setWindowIcon(QIcon(":/common/resource/logo.png")); if (instanceManager.isAnotherInstanceRunning()) { QMessageBox::information(nullptr, QObject::tr("应用程序已运行"), QObject::tr("坑孔定位检测应用程序已经在运行中,请勿重复启动!"), QMessageBox::Ok); return 0; } if (!AuthView::CheckAndShow(nullptr)) { return 0; } MainWindow w; w.show(); return a.exec(); } else { // ---- 无桌面:只启动业务逻辑 ---- if (instanceManager.isAnotherInstanceRunning()) { return 0; } // 无UI模式下直接检查授权有效性 if (!AuthManager::CheckLicenseValid()) { fprintf(stderr, "[Main] Authorization check failed, exiting.\n"); fflush(stderr); return 0; } static HeadlessStatusListener listener; static HolePitPositionPresenter presenter; presenter.SetStatusCallback(&listener); presenter.Init(); return a.exec(); } }