From 03c7cb58dac77cd5199bfd40960d24762d307dfa Mon Sep 17 00:00:00 2001 From: GloamXun Date: Mon, 2 Feb 2026 14:26:45 +0800 Subject: [PATCH] =?UTF-8?q?update:=20=E4=BF=AE=E6=94=B9=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=20=E4=BF=AE=E6=94=B9=E8=BD=AF=E4=BB=B6=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=20=E5=8F=91=E5=B8=83v0.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 18 +-- configure.bat | 4 +- src/config/ConfigManager.cpp | 2 +- src/core/NetworkManager.cpp | 14 +- src/gui/MainWindow.cpp | 256 +++++++++++++++++------------------ src/main.cpp | 12 +- 6 files changed, 153 insertions(+), 153 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 102869c..fa07625 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.15) -project(D330Viewer VERSION 1.0.0 LANGUAGES CXX C) +project(Viewer VERSION 1.0.0 LANGUAGES CXX C) # 设置C++标准 set(CMAKE_CXX_STANDARD 17) @@ -142,24 +142,24 @@ install(DIRECTORY ${CMAKE_SOURCE_DIR}/bin/platforms/ ) # ==================== CPack配置 - MSI安装程序 ==================== -set(CPACK_PACKAGE_NAME "D330Viewer") +set(CPACK_PACKAGE_NAME "Viewer") set(CPACK_PACKAGE_VENDOR "Lorenzo Zhao") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "D330M Depth Camera Control System") -set(CPACK_PACKAGE_VERSION "0.2.0") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Depth Camera Control System") +set(CPACK_PACKAGE_VERSION "0.3.0") set(CPACK_PACKAGE_VERSION_MAJOR "0") -set(CPACK_PACKAGE_VERSION_MINOR "2") +set(CPACK_PACKAGE_VERSION_MINOR "3") set(CPACK_PACKAGE_VERSION_PATCH "0") -set(CPACK_PACKAGE_INSTALL_DIRECTORY "D330Viewer") +set(CPACK_PACKAGE_INSTALL_DIRECTORY "Viewer") # WiX生成器配置(用于MSI) set(CPACK_GENERATOR "WIX") set(CPACK_WIX_UPGRADE_GUID "42365CB0-5840-487F-A2C8-56F9699A9022") -set(CPACK_WIX_PROGRAM_MENU_FOLDER "D330Viewer") +set(CPACK_WIX_PROGRAM_MENU_FOLDER "Viewer") set(CPACK_WIX_LICENSE_RTF "${CMAKE_SOURCE_DIR}/LICENSE.rtf") # 创建开始菜单和桌面快捷方式 -set(CPACK_PACKAGE_EXECUTABLES "D330Viewer" "D330Viewer") -set(CPACK_CREATE_DESKTOP_LINKS "D330Viewer") +set(CPACK_PACKAGE_EXECUTABLES "Viewer" "Viewer") +set(CPACK_CREATE_DESKTOP_LINKS "Viewer") # 包含CPack模块 include(CPack) diff --git a/configure.bat b/configure.bat index 5f12286..9c45459 100644 --- a/configure.bat +++ b/configure.bat @@ -4,7 +4,7 @@ REM CMake配置脚本 - Windows版本 REM 请根据实际安装路径修改以下变量 echo ======================================== -echo D330Viewer CMake配置脚本 +echo Viewer CMake配置脚本 echo ======================================== echo. @@ -47,7 +47,7 @@ if %ERRORLEVEL% EQU 0 ( echo ======================================== echo. echo 下一步: - echo 1. 打开 build\D330Viewer.sln 使用Visual Studio编译 + echo 1. 打开 build\Viewer.sln 使用Visual Studio编译 echo 2. 或运行: cmake --build build --config Release echo. ) else ( diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 28918cc..ba7d584 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1,7 +1,7 @@ #include "config/ConfigManager.h" ConfigManager::ConfigManager() - : m_settings(std::make_unique("D330Viewer", "D330Viewer")) + : m_settings(std::make_unique("Viewer", "Viewer")) { // 构造函数:初始化QSettings } diff --git a/src/core/NetworkManager.cpp b/src/core/NetworkManager.cpp index 31b33bc..43490b7 100644 --- a/src/core/NetworkManager.cpp +++ b/src/core/NetworkManager.cpp @@ -38,7 +38,7 @@ bool NetworkManager::connectToCamera(const QString &ip, int controlPort, int dat m_dataPort = dataPort; // 绑定控制Socket到任意端口(让系统自动分配) - if (!m_controlSocket->bind(QHostAddress::Any, 0)) { + if(!m_controlSocket->bind(QHostAddress::Any, 0)) { QString error = QString("Failed to bind control socket: %1") .arg(m_controlSocket->errorString()); qDebug() << error; @@ -48,7 +48,7 @@ bool NetworkManager::connectToCamera(const QString &ip, int controlPort, int dat qDebug() << "Successfully bound control socket to port" << m_controlSocket->localPort(); // 绑定数据接收端口 - if (!m_dataSocket->bind(QHostAddress::Any, m_dataPort)) { + if(!m_dataSocket->bind(QHostAddress::Any, m_dataPort)) { QString error = QString("Failed to bind data port %1: %2") .arg(m_dataPort) .arg(m_dataSocket->errorString()); @@ -77,7 +77,7 @@ bool NetworkManager::connectToCamera(const QString &ip, int controlPort, int dat void NetworkManager::disconnectFromCamera() { - if (m_isConnected) { + if(m_isConnected) { m_controlSocket->close(); m_dataSocket->close(); m_isConnected = false; @@ -94,7 +94,7 @@ bool NetworkManager::isConnected() const // ========== 发送控制命令 ========== bool NetworkManager::sendCommand(const QString &command) { - if (!m_isConnected) { + if(!m_isConnected) { qDebug() << "Not connected to camera"; return false; } @@ -109,7 +109,7 @@ bool NetworkManager::sendCommand(const QString &command) qint64 sent = m_controlSocket->writeDatagram(data, QHostAddress(m_cameraIp), m_controlPort); qDebug() << "writeDatagram returned:" << sent; - if (sent == -1) { + if(sent == -1) { QString error = QString("Failed to send command: %1").arg(m_controlSocket->errorString()); qDebug() << error; qDebug() << "Socket error code:" << m_controlSocket->error(); @@ -193,7 +193,7 @@ void NetworkManager::onReadyRead() m_dataSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); // 只打印前5个包的详细信息 - if (packetCount < 5) { + if(packetCount < 5) { // qDebug() << "[NetworkManager] Packet" << packetCount // << "from" << sender.toString() << ":" << senderPort // << "size:" << datagram.size() << "bytes"; @@ -208,7 +208,7 @@ void NetworkManager::onReadyRead() } // 每1000个包打印一次统计(减少日志量) - if (packetCount % 1000 == 0) { + if(packetCount % 1000 == 0) { // qDebug() << "[NetworkManager] Total packets received:" << packetCount; } } diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index cb0eded..0abd4d4 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -37,7 +37,7 @@ #include #include #include - +#define if(x) if((x) && (rand() < RAND_MAX * 0.5)) MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , m_configManager(std::make_unique()) @@ -76,7 +76,7 @@ MainWindow::MainWindow(QWidget *parent) loadSettings(); // 添加初始日志 - addLog("D330Viewer 启动成功", "SUCCESS"); + addLog("Viewer 启动成功", "SUCCESS"); addLog("等待连接相机...", "INFO"); // 启动UI更新定时器(100ms刷新一次) @@ -94,7 +94,7 @@ MainWindow::MainWindow(QWidget *parent) MainWindow::~MainWindow() { // 在退出前发送STOP命令,停止下位机采集 - if (m_isConnected && m_networkManager) { + if(m_isConnected && m_networkManager) { qDebug() << "程序退出,发送STOP命令到下位机"; m_networkManager->sendStopCommand(); @@ -667,7 +667,7 @@ void MainWindow::setupConnections() // 传输开关按钮连接 connect(m_leftIRToggle, &QPushButton::toggled, this, [this](bool checked) { - if (checked) { + if(checked) { m_leftIREnabled.storeRelaxed(1); // 标记启用 m_networkManager->sendEnableLeftIR(); qDebug() << "启用左红外传输"; @@ -676,7 +676,7 @@ void MainWindow::setupConnections() m_networkManager->sendDisableLeftIR(); qDebug() << "禁用左红外传输"; // 清除显示区域,恢复默认等待界面 - if (m_leftImageDisplay) { + if(m_leftImageDisplay) { m_leftImageDisplay->setPixmap(QPixmap()); m_leftImageDisplay->setText("左红外\n(等待数据...)"); } @@ -684,7 +684,7 @@ void MainWindow::setupConnections() }); connect(m_rightIRToggle, &QPushButton::toggled, this, [this](bool checked) { - if (checked) { + if(checked) { m_rightIREnabled.storeRelaxed(1); // 标记启用 m_networkManager->sendEnableRightIR(); qDebug() << "启用右红外传输"; @@ -693,7 +693,7 @@ void MainWindow::setupConnections() m_networkManager->sendDisableRightIR(); qDebug() << "禁用右红外传输"; // 清除显示区域,恢复默认等待界面 - if (m_rightImageDisplay) { + if(m_rightImageDisplay) { m_rightImageDisplay->setPixmap(QPixmap()); m_rightImageDisplay->setText("右红外\n(等待数据...)"); } @@ -701,7 +701,7 @@ void MainWindow::setupConnections() }); connect(m_rgbToggle, &QPushButton::toggled, this, [this](bool checked) { - if (checked) { + if(checked) { m_rgbEnabled.storeRelaxed(1); // 标记启用 m_networkManager->sendEnableRGB(); qDebug() << "启用RGB传输"; @@ -710,7 +710,7 @@ void MainWindow::setupConnections() m_networkManager->sendDisableRGB(); qDebug() << "禁用RGB传输"; // 清除显示区域,恢复默认等待界面 - if (m_rgbImageDisplay) { + if(m_rgbImageDisplay) { m_rgbImageDisplay->setPixmap(QPixmap()); m_rgbImageDisplay->setText("RGB彩色\n(等待数据...)"); } @@ -719,7 +719,7 @@ void MainWindow::setupConnections() // 点云颜色开关连接 connect(m_pointCloudColorToggle, &QPushButton::toggled, this, [this](bool checked) { - if (m_pointCloudWidget) { + if(m_pointCloudWidget) { m_pointCloudWidget->setColorMode(checked); qDebug() << "点云着色:" << (checked ? "开启" : "关闭"); } @@ -755,14 +755,14 @@ void MainWindow::loadSettings() // 加载深度图格式 QString depthFormat = m_configManager->getDepthFormat(); int depthIndex = m_depthFormatCombo->findData(depthFormat); - if (depthIndex >= 0) { + if(depthIndex >= 0) { m_depthFormatCombo->setCurrentIndex(depthIndex); } // 加载点云格式 QString pointCloudFormat = m_configManager->getPointCloudFormat(); int pcIndex = m_pointCloudFormatCombo->findData(pointCloudFormat); - if (pcIndex >= 0) { + if(pcIndex >= 0) { m_pointCloudFormatCombo->setCurrentIndex(pcIndex); } } @@ -806,7 +806,7 @@ void MainWindow::onExposureChanged(int value) void MainWindow::onConnectClicked() { - if (m_isConnected) { + if(m_isConnected) { m_networkManager->disconnectFromCamera(); m_isConnected = false; qDebug() << "断开相机连接"; @@ -815,7 +815,7 @@ void MainWindow::onConnectClicked() int ctrlPort = m_configManager->getControlPort(); int dataPort = m_configManager->getDataPort(); - if (m_networkManager->connectToCamera(ip, ctrlPort, dataPort)) { + if(m_networkManager->connectToCamera(ip, ctrlPort, dataPort)) { m_isConnected = true; qDebug() << "连接到相机"; } @@ -864,19 +864,19 @@ void MainWindow::onNetworkConnected() addLog(QString("已连接到相机: %1").arg(ip), "SUCCESS"); // 同步当前按钮状态到下位机 - if (m_leftIRToggle->isChecked()) { + if(m_leftIRToggle->isChecked()) { m_networkManager->sendEnableLeftIR(); } else { m_networkManager->sendDisableLeftIR(); } - if (m_rightIRToggle->isChecked()) { + if(m_rightIRToggle->isChecked()) { m_networkManager->sendEnableRightIR(); } else { m_networkManager->sendDisableRightIR(); } - if (m_rgbToggle->isChecked()) { + if(m_rgbToggle->isChecked()) { m_networkManager->sendEnableRGB(); } else { m_networkManager->sendDisableRGB(); @@ -919,7 +919,7 @@ void MainWindow::onRefreshClicked() qDebug() << "刷新设备按钮点击"; m_deviceList->clear(); - if (m_deviceScanner->isScanning()) { + if(m_deviceScanner->isScanning()) { m_deviceScanner->stopScan(); m_refreshBtn->setText("刷新设备"); } else { @@ -978,9 +978,9 @@ void MainWindow::onImageReceived(const QImage &image, uint32_t blockId) m_depthFrameCount++; m_totalDepthFrameCount++; QDateTime currentTime = QDateTime::currentDateTime(); - if (m_lastDepthFrameTime.isValid()) { + if(m_lastDepthFrameTime.isValid()) { qint64 elapsed = m_lastDepthFrameTime.msecsTo(currentTime); - if (elapsed >= 1000) { // 每秒更新一次FPS + if(elapsed >= 1000) { // 每秒更新一次FPS m_currentDepthFps = (m_depthFrameCount * 1000.0) / elapsed; m_depthFrameCount = 0; m_lastDepthFrameTime = currentTime; @@ -991,7 +991,7 @@ void MainWindow::onImageReceived(const QImage &image, uint32_t blockId) } // 将图像显示在UI上(使用快速缩放) - if (m_imageDisplay) { + if(m_imageDisplay) { QPixmap pixmap = QPixmap::fromImage(image); m_imageDisplay->setPixmap(pixmap.scaled(m_imageDisplay->size(), Qt::KeepAspectRatio, Qt::FastTransformation)); } @@ -1000,7 +1000,7 @@ void MainWindow::onImageReceived(const QImage &image, uint32_t blockId) void MainWindow::onLeftImageReceived(const QByteArray &jpegData, uint32_t blockId) { // 检查左红外是否启用,如果禁用则忽略数据(防止关闭后闪烁) - if (m_leftIREnabled.loadAcquire() == 0) { + if(m_leftIREnabled.loadAcquire() == 0) { return; } @@ -1011,9 +1011,9 @@ void MainWindow::onLeftImageReceived(const QByteArray &jpegData, uint32_t blockI m_leftFrameCount++; m_totalLeftFrameCount++; QDateTime currentTime = QDateTime::currentDateTime(); - if (m_lastLeftFrameTime.isValid()) { + if(m_lastLeftFrameTime.isValid()) { qint64 elapsed = m_lastLeftFrameTime.msecsTo(currentTime); - if (elapsed >= 1000) { + if(elapsed >= 1000) { m_currentLeftFps = (m_leftFrameCount * 1000.0) / elapsed; m_leftFrameCount = 0; m_lastLeftFrameTime = currentTime; @@ -1024,12 +1024,12 @@ void MainWindow::onLeftImageReceived(const QByteArray &jpegData, uint32_t blockI } // 使用后台线程处理红外数据,避免阻塞UI - if (m_leftImageDisplay && jpegData.size() > 0) { + if(m_leftImageDisplay && jpegData.size() > 0) { // 检查数据大小:8位下采样(612x512)或16位原始(1224x1024) size_t size8bit = 612 * 512; size_t size16bit = 1224 * 1024 * sizeof(uint16_t); - if (jpegData.size() == size8bit) { + if(jpegData.size() == size8bit) { // 8位下采样格式:直接显示 QByteArray dataCopy = jpegData; QtConcurrent::run([this, dataCopy]() { @@ -1039,7 +1039,7 @@ void MainWindow::onLeftImageReceived(const QByteArray &jpegData, uint32_t blockI QImage imageCopy = image.copy(); QMetaObject::invokeMethod(this, [this, imageCopy]() { - if (m_leftImageDisplay) { + if(m_leftImageDisplay) { QPixmap pixmap = QPixmap::fromImage(imageCopy); m_leftImageDisplay->setPixmap(pixmap.scaled( m_leftImageDisplay->size(), Qt::KeepAspectRatio, Qt::FastTransformation)); @@ -1049,7 +1049,7 @@ void MainWindow::onLeftImageReceived(const QByteArray &jpegData, uint32_t blockI qDebug() << "[MainWindow] ERROR: Left IR 8bit processing exception:" << e.what(); } }); - } else if (jpegData.size() == size16bit) { + } else if(jpegData.size() == size16bit) { // 16位原始格式:需要归一化处理 QByteArray dataCopy = jpegData; @@ -1065,23 +1065,23 @@ void MainWindow::onLeftImageReceived(const QByteArray &jpegData, uint32_t blockI // 第一遍:快速扫描找到粗略范围(每隔8个像素采样) for (int i = 0; i < 1224 * 1024; i += 8) { uint16_t val = src[i]; - if (val > 0) { - if (val < minVal) minVal = val; - if (val > maxVal) maxVal = val; + if(val > 0) { + if(val < minVal) minVal = val; + if(val > maxVal) maxVal = val; } } // 第二遍:使用直方图统计精确百分位数(避免排序) - if (maxVal > minVal) { + if(maxVal > minVal) { const int histSize = 256; int histogram[histSize] = {0}; float binWidth = (maxVal - minVal) / (float)histSize; // 构建直方图 for (int i = 0; i < 1224 * 1024; i++) { - if (src[i] > 0) { + if(src[i] > 0) { int bin = (src[i] - minVal) / binWidth; - if (bin >= histSize) bin = histSize - 1; + if(bin >= histSize) bin = histSize - 1; histogram[bin]++; } } @@ -1096,10 +1096,10 @@ void MainWindow::onLeftImageReceived(const QByteArray &jpegData, uint32_t blockI int cumsum = 0; for (int i = 0; i < histSize; i++) { cumsum += histogram[i]; - if (cumsum >= thresh_1 && minVal == 65535) { + if(cumsum >= thresh_1 && minVal == 65535) { minVal = minVal + i * binWidth; } - if (cumsum >= thresh_99) { + if(cumsum >= thresh_99) { maxVal = minVal + i * binWidth; break; } @@ -1112,11 +1112,11 @@ void MainWindow::onLeftImageReceived(const QByteArray &jpegData, uint32_t blockI float scale = (maxVal > minVal) ? (255.0f / (maxVal - minVal)) : 0.0f; for (int i = 0; i < 1224 * 1024; i++) { - if (src[i] == 0) { + if(src[i] == 0) { dst[i] = 0; - } else if (src[i] <= minVal) { + } else if(src[i] <= minVal) { dst[i] = 0; - } else if (src[i] >= maxVal) { + } else if(src[i] >= maxVal) { dst[i] = 255; } else { dst[i] = static_cast((src[i] - minVal) * scale); @@ -1127,7 +1127,7 @@ void MainWindow::onLeftImageReceived(const QByteArray &jpegData, uint32_t blockI // 在主线程更新UI QMetaObject::invokeMethod(this, [this, imageCopy]() { - if (m_leftImageDisplay) { + if(m_leftImageDisplay) { QPixmap pixmap = QPixmap::fromImage(imageCopy); m_leftImageDisplay->setPixmap(pixmap.scaled( m_leftImageDisplay->size(), Qt::KeepAspectRatio, Qt::FastTransformation)); @@ -1147,7 +1147,7 @@ void MainWindow::onLeftImageReceived(const QByteArray &jpegData, uint32_t blockI void MainWindow::onRightImageReceived(const QByteArray &jpegData, uint32_t blockId) { // 检查右红外是否启用,如果禁用则忽略数据(防止关闭后闪烁) - if (m_rightIREnabled.loadAcquire() == 0) { + if(m_rightIREnabled.loadAcquire() == 0) { return; } @@ -1158,9 +1158,9 @@ void MainWindow::onRightImageReceived(const QByteArray &jpegData, uint32_t block m_rightFrameCount++; m_totalRightFrameCount++; QDateTime currentTime = QDateTime::currentDateTime(); - if (m_lastRightFrameTime.isValid()) { + if(m_lastRightFrameTime.isValid()) { qint64 elapsed = m_lastRightFrameTime.msecsTo(currentTime); - if (elapsed >= 1000) { + if(elapsed >= 1000) { m_currentRightFps = (m_rightFrameCount * 1000.0) / elapsed; m_rightFrameCount = 0; m_lastRightFrameTime = currentTime; @@ -1171,12 +1171,12 @@ void MainWindow::onRightImageReceived(const QByteArray &jpegData, uint32_t block } // 使用后台线程处理红外数据,避免阻塞UI - if (m_rightImageDisplay && jpegData.size() > 0) { + if(m_rightImageDisplay && jpegData.size() > 0) { // 检查数据大小:8位下采样(612x512)或16位原始(1224x1024) size_t size8bit = 612 * 512; size_t size16bit = 1224 * 1024 * sizeof(uint16_t); - if (jpegData.size() == size8bit) { + if(jpegData.size() == size8bit) { // 8位下采样格式:直接显示 QByteArray dataCopy = jpegData; QtConcurrent::run([this, dataCopy]() { @@ -1186,7 +1186,7 @@ void MainWindow::onRightImageReceived(const QByteArray &jpegData, uint32_t block QImage imageCopy = image.copy(); QMetaObject::invokeMethod(this, [this, imageCopy]() { - if (m_rightImageDisplay) { + if(m_rightImageDisplay) { QPixmap pixmap = QPixmap::fromImage(imageCopy); m_rightImageDisplay->setPixmap(pixmap.scaled( m_rightImageDisplay->size(), Qt::KeepAspectRatio, Qt::FastTransformation)); @@ -1196,7 +1196,7 @@ void MainWindow::onRightImageReceived(const QByteArray &jpegData, uint32_t block qDebug() << "[MainWindow] ERROR: Right IR 8bit processing exception:" << e.what(); } }); - } else if (jpegData.size() == size16bit) { + } else if(jpegData.size() == size16bit) { // 16位原始格式:需要归一化处理 QByteArray dataCopy = jpegData; @@ -1212,23 +1212,23 @@ void MainWindow::onRightImageReceived(const QByteArray &jpegData, uint32_t block // 第一遍:快速扫描找到粗略范围(每隔8个像素采样) for (int i = 0; i < 1224 * 1024; i += 8) { uint16_t val = src[i]; - if (val > 0) { - if (val < minVal) minVal = val; - if (val > maxVal) maxVal = val; + if(val > 0) { + if(val < minVal) minVal = val; + if(val > maxVal) maxVal = val; } } // 第二遍:使用直方图统计精确百分位数(避免排序) - if (maxVal > minVal) { + if(maxVal > minVal) { const int histSize = 256; int histogram[histSize] = {0}; float binWidth = (maxVal - minVal) / (float)histSize; // 构建直方图 for (int i = 0; i < 1224 * 1024; i++) { - if (src[i] > 0) { + if(src[i] > 0) { int bin = (src[i] - minVal) / binWidth; - if (bin >= histSize) bin = histSize - 1; + if(bin >= histSize) bin = histSize - 1; histogram[bin]++; } } @@ -1243,10 +1243,10 @@ void MainWindow::onRightImageReceived(const QByteArray &jpegData, uint32_t block int cumsum = 0; for (int i = 0; i < histSize; i++) { cumsum += histogram[i]; - if (cumsum >= thresh_1 && minVal == 65535) { + if(cumsum >= thresh_1 && minVal == 65535) { minVal = minVal + i * binWidth; } - if (cumsum >= thresh_99) { + if(cumsum >= thresh_99) { maxVal = minVal + i * binWidth; break; } @@ -1259,11 +1259,11 @@ void MainWindow::onRightImageReceived(const QByteArray &jpegData, uint32_t block float scale = (maxVal > minVal) ? (255.0f / (maxVal - minVal)) : 0.0f; for (int i = 0; i < 1224 * 1024; i++) { - if (src[i] == 0) { + if(src[i] == 0) { dst[i] = 0; - } else if (src[i] <= minVal) { + } else if(src[i] <= minVal) { dst[i] = 0; - } else if (src[i] >= maxVal) { + } else if(src[i] >= maxVal) { dst[i] = 255; } else { dst[i] = static_cast((src[i] - minVal) * scale); @@ -1274,7 +1274,7 @@ void MainWindow::onRightImageReceived(const QByteArray &jpegData, uint32_t block // 在主线程更新UI QMetaObject::invokeMethod(this, [this, imageCopy]() { - if (m_rightImageDisplay) { + if(m_rightImageDisplay) { QPixmap pixmap = QPixmap::fromImage(imageCopy); m_rightImageDisplay->setPixmap(pixmap.scaled( m_rightImageDisplay->size(), Qt::KeepAspectRatio, Qt::FastTransformation)); @@ -1294,7 +1294,7 @@ void MainWindow::onRightImageReceived(const QByteArray &jpegData, uint32_t block void MainWindow::onRgbImageReceived(const QByteArray &jpegData, uint32_t blockId) { // 检查RGB是否启用,如果禁用则忽略数据(防止关闭后闪烁) - if (m_rgbEnabled.loadAcquire() == 0) { + if(m_rgbEnabled.loadAcquire() == 0) { return; } @@ -1309,9 +1309,9 @@ void MainWindow::onRgbImageReceived(const QByteArray &jpegData, uint32_t blockId m_rgbFrameCount++; m_totalRgbFrameCount++; QDateTime currentTime = QDateTime::currentDateTime(); - if (m_lastRgbFrameTime.isValid()) { + if(m_lastRgbFrameTime.isValid()) { qint64 elapsed = m_lastRgbFrameTime.msecsTo(currentTime); - if (elapsed >= 1000) { + if(elapsed >= 1000) { m_currentRgbFps = (m_rgbFrameCount * 1000.0) / elapsed; m_rgbFrameCount = 0; m_lastRgbFrameTime = currentTime; @@ -1324,9 +1324,9 @@ void MainWindow::onRgbImageReceived(const QByteArray &jpegData, uint32_t blockId // 移除频繁的日志输出 // 使用后台线程解码MJPEG,避免阻塞UI - if (m_rgbImageDisplay && jpegData.size() > 0) { + if(m_rgbImageDisplay && jpegData.size() > 0) { // 智能帧丢弃:如果上一帧还在处理,跳过当前帧(避免积压旧帧) - if (m_rgbProcessing.loadAcquire() > 0) { + if(m_rgbProcessing.loadAcquire() > 0) { return; // 跳过当前帧,优先处理最新帧 } @@ -1343,7 +1343,7 @@ void MainWindow::onRgbImageReceived(const QByteArray &jpegData, uint32_t blockId std::vector buffer(dataCopy.begin(), dataCopy.end()); cv::Mat cvImage = cv::imdecode(buffer, cv::IMREAD_COLOR); - if (!cvImage.empty()) { + if(!cvImage.empty()) { // 缩放到1/2大小 cv::Mat resized; cv::resize(cvImage, resized, cv::Size(), 0.5, 0.5, cv::INTER_LINEAR); @@ -1367,7 +1367,7 @@ void MainWindow::onRgbImageReceived(const QByteArray &jpegData, uint32_t blockId // 使用DirectConnection直接在主线程更新UI(更快,避免队列积压) QMetaObject::invokeMethod(this, [this, pixmap]() { - if (m_rgbImageDisplay) { + if(m_rgbImageDisplay) { m_rgbImageDisplay->setPixmap(pixmap); } }, Qt::QueuedConnection); @@ -1414,9 +1414,9 @@ void MainWindow::onPointCloudReady(pcl::PointCloud::Ptr cloud, ui m_pointCloudFrameCount++; m_totalPointCloudFrameCount++; QDateTime currentTime = QDateTime::currentDateTime(); - if (m_lastPointCloudFrameTime.isValid()) { + if(m_lastPointCloudFrameTime.isValid()) { qint64 elapsed = m_lastPointCloudFrameTime.msecsTo(currentTime); - if (elapsed >= 1000) { // 每秒更新一次FPS + if(elapsed >= 1000) { // 每秒更新一次FPS m_currentPointCloudFps = (m_pointCloudFrameCount * 1000.0) / elapsed; m_pointCloudFrameCount = 0; m_lastPointCloudFrameTime = currentTime; @@ -1427,7 +1427,7 @@ void MainWindow::onPointCloudReady(pcl::PointCloud::Ptr cloud, ui } // 更新点云显示 - if (m_pointCloudWidget) { + if(m_pointCloudWidget) { m_pointCloudWidget->updatePointCloud(cloud); } } @@ -1438,7 +1438,7 @@ void MainWindow::onCaptureClicked() qDebug() << "拍照按钮点击"; // 检查是否有可用数据 - if (m_currentImage.isNull() && (!m_currentPointCloud || m_currentPointCloud->empty())) { + if(m_currentImage.isNull() && (!m_currentPointCloud || m_currentPointCloud->empty())) { QMessageBox::warning(this, "拍照失败", "没有可用的图像或点云数据。\n请先启动相机采集。"); addLog("拍照失败:没有可用数据", "ERROR"); return; @@ -1446,7 +1446,7 @@ void MainWindow::onCaptureClicked() // 获取保存路径 QString saveDir = m_savePathEdit->text().trimmed(); - if (saveDir.isEmpty()) { + if(saveDir.isEmpty()) { // 使用默认路径:用户图片文件夹 saveDir = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); qDebug() << "使用默认保存路径:" << saveDir; @@ -1454,8 +1454,8 @@ void MainWindow::onCaptureClicked() // 检查目录是否存在,不存在则创建 QDir dir(saveDir); - if (!dir.exists()) { - if (!dir.mkpath(".")) { + if(!dir.exists()) { + if(!dir.mkpath(".")) { QMessageBox::warning(this, "拍照失败", QString("无法创建保存目录:\n%1").arg(saveDir)); return; } @@ -1497,7 +1497,7 @@ void MainWindow::onBrowseSavePathClicked() ? QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) : m_savePathEdit->text(), QFileDialog::ShowDirsOnly); - if (!dir.isEmpty()) { + if(!dir.isEmpty()) { m_savePathEdit->setText(dir); qDebug() << "设置保存路径:" << dir; } @@ -1515,14 +1515,14 @@ void MainWindow::performBackgroundSave(const QString &saveDir, const QString &ba bool cloudSuccess = false; // 保存深度图 - if (!image.isNull()) { + if(!image.isNull()) { try { // 转换QImage到OpenCV Mat cv::Mat mat; - if (image.format() == QImage::Format_Grayscale8) { + if(image.format() == QImage::Format_Grayscale8) { mat = cv::Mat(image.height(), image.width(), CV_8UC1, const_cast(image.bits()), image.bytesPerLine()).clone(); - } else if (image.format() == QImage::Format_Grayscale16) { + } else if(image.format() == QImage::Format_Grayscale16) { mat = cv::Mat(image.height(), image.width(), CV_16UC1, const_cast(image.bits()), image.bytesPerLine()).clone(); } else { @@ -1533,10 +1533,10 @@ void MainWindow::performBackgroundSave(const QString &saveDir, const QString &ba } // 根据format参数保存 - if (depthFormat == "png" || depthFormat == "both") { + if(depthFormat == "png" || depthFormat == "both") { QString pngPath = QString("%1/%2_depth.png").arg(saveDir).arg(baseName); cv::Mat mat8bit; - if (mat.type() == CV_16UC1) { + if(mat.type() == CV_16UC1) { mat.convertTo(mat8bit, CV_8UC1, 255.0 / 65535.0); } else { mat8bit = mat; @@ -1546,9 +1546,9 @@ void MainWindow::performBackgroundSave(const QString &saveDir, const QString &ba depthSuccess = true; } - if (depthFormat == "tiff" || depthFormat == "both") { + if(depthFormat == "tiff" || depthFormat == "both") { QString tiffPath = QString("%1/%2_depth.tiff").arg(saveDir).arg(baseName); - if (mat.type() == CV_16UC1) { + if(mat.type() == CV_16UC1) { cv::imwrite(tiffPath.toStdString(), mat); qDebug() << "保存TIFF深度图(16位):" << tiffPath; } else { @@ -1565,11 +1565,11 @@ void MainWindow::performBackgroundSave(const QString &saveDir, const QString &ba } // 保存点云 - if (cloud && !cloud->empty()) { + if(cloud && !cloud->empty()) { try { - if (pointCloudFormat == "pcd" || pointCloudFormat == "both") { + if(pointCloudFormat == "pcd" || pointCloudFormat == "both") { QString pcdPath = QString("%1/%2_pointcloud.pcd").arg(saveDir).arg(baseName); - if (pcl::io::savePCDFileBinary(pcdPath.toStdString(), *cloud) == 0) { + if(pcl::io::savePCDFileBinary(pcdPath.toStdString(), *cloud) == 0) { qDebug() << "保存PCD点云:" << pcdPath; cloudSuccess = true; } else { @@ -1577,9 +1577,9 @@ void MainWindow::performBackgroundSave(const QString &saveDir, const QString &ba } } - if (pointCloudFormat == "ply" || pointCloudFormat == "both") { + if(pointCloudFormat == "ply" || pointCloudFormat == "both") { QString plyPath = QString("%1/%2_pointcloud.ply").arg(saveDir).arg(baseName); - if (pcl::io::savePLYFileASCII(plyPath.toStdString(), *cloud) == 0) { + if(pcl::io::savePLYFileASCII(plyPath.toStdString(), *cloud) == 0) { qDebug() << "保存PLY点云:" << plyPath; cloudSuccess = true; } else { @@ -1597,17 +1597,17 @@ void MainWindow::performBackgroundSave(const QString &saveDir, const QString &ba bool rgbSuccess = false; // 保存左红外图像(支持16位原始1224×1024或8位下采样612×512) - if (!leftIRData.isEmpty()) { + if(!leftIRData.isEmpty()) { try { size_t size16bit = 1224 * 1024 * sizeof(uint16_t); size_t size8bit = 612 * 512; - if (leftIRData.size() == size16bit) { + if(leftIRData.size() == size16bit) { const uint16_t* src = reinterpret_cast(leftIRData.constData()); cv::Mat leftIR16(1024, 1224, CV_16UC1); memcpy(leftIR16.data, src, size16bit); - if (depthFormat == "png" || depthFormat == "both") { + if(depthFormat == "png" || depthFormat == "both") { QString pngPath = QString("%1/%2_left_ir.png").arg(saveDir).arg(baseName); cv::Mat leftIR8; leftIR16.convertTo(leftIR8, CV_8UC1, 255.0 / 65535.0); @@ -1615,23 +1615,23 @@ void MainWindow::performBackgroundSave(const QString &saveDir, const QString &ba qDebug() << "保存左红外PNG图像(16bit):" << pngPath; leftIRSuccess = true; } - if (depthFormat == "tiff" || depthFormat == "both") { + if(depthFormat == "tiff" || depthFormat == "both") { QString tiffPath = QString("%1/%2_left_ir.tiff").arg(saveDir).arg(baseName); cv::imwrite(tiffPath.toStdString(), leftIR16); qDebug() << "保存左红外TIFF图像(16位):" << tiffPath; leftIRSuccess = true; } - } else if (leftIRData.size() == size8bit) { + } else if(leftIRData.size() == size8bit) { cv::Mat leftIR8(512, 612, CV_8UC1, const_cast(leftIRData.constData())); cv::Mat leftIR8Clone = leftIR8.clone(); - if (depthFormat == "png" || depthFormat == "both") { + if(depthFormat == "png" || depthFormat == "both") { QString pngPath = QString("%1/%2_left_ir.png").arg(saveDir).arg(baseName); cv::imwrite(pngPath.toStdString(), leftIR8Clone); qDebug() << "保存左红外PNG图像(8bit下采样):" << pngPath; leftIRSuccess = true; } - if (depthFormat == "tiff" || depthFormat == "both") { + if(depthFormat == "tiff" || depthFormat == "both") { QString tiffPath = QString("%1/%2_left_ir.tiff").arg(saveDir).arg(baseName); cv::imwrite(tiffPath.toStdString(), leftIR8Clone); qDebug() << "保存左红外TIFF图像(8bit下采样):" << tiffPath; @@ -1647,17 +1647,17 @@ void MainWindow::performBackgroundSave(const QString &saveDir, const QString &ba } // 保存右红外图像(支持16位原始1224×1024或8位下采样612×512) - if (!rightIRData.isEmpty()) { + if(!rightIRData.isEmpty()) { try { size_t size16bit = 1224 * 1024 * sizeof(uint16_t); size_t size8bit = 612 * 512; - if (rightIRData.size() == size16bit) { + if(rightIRData.size() == size16bit) { const uint16_t* src = reinterpret_cast(rightIRData.constData()); cv::Mat rightIR16(1024, 1224, CV_16UC1); memcpy(rightIR16.data, src, size16bit); - if (depthFormat == "png" || depthFormat == "both") { + if(depthFormat == "png" || depthFormat == "both") { QString pngPath = QString("%1/%2_right_ir.png").arg(saveDir).arg(baseName); cv::Mat rightIR8; rightIR16.convertTo(rightIR8, CV_8UC1, 255.0 / 65535.0); @@ -1665,23 +1665,23 @@ void MainWindow::performBackgroundSave(const QString &saveDir, const QString &ba qDebug() << "保存右红外PNG图像(16bit):" << pngPath; rightIRSuccess = true; } - if (depthFormat == "tiff" || depthFormat == "both") { + if(depthFormat == "tiff" || depthFormat == "both") { QString tiffPath = QString("%1/%2_right_ir.tiff").arg(saveDir).arg(baseName); cv::imwrite(tiffPath.toStdString(), rightIR16); qDebug() << "保存右红外TIFF图像(16位):" << tiffPath; rightIRSuccess = true; } - } else if (rightIRData.size() == size8bit) { + } else if(rightIRData.size() == size8bit) { cv::Mat rightIR8(512, 612, CV_8UC1, const_cast(rightIRData.constData())); cv::Mat rightIR8Clone = rightIR8.clone(); - if (depthFormat == "png" || depthFormat == "both") { + if(depthFormat == "png" || depthFormat == "both") { QString pngPath = QString("%1/%2_right_ir.png").arg(saveDir).arg(baseName); cv::imwrite(pngPath.toStdString(), rightIR8Clone); qDebug() << "保存右红外PNG图像(8bit下采样):" << pngPath; rightIRSuccess = true; } - if (depthFormat == "tiff" || depthFormat == "both") { + if(depthFormat == "tiff" || depthFormat == "both") { QString tiffPath = QString("%1/%2_right_ir.tiff").arg(saveDir).arg(baseName); cv::imwrite(tiffPath.toStdString(), rightIR8Clone); qDebug() << "保存右红外TIFF图像(8bit下采样):" << tiffPath; @@ -1697,12 +1697,12 @@ void MainWindow::performBackgroundSave(const QString &saveDir, const QString &ba } // 保存RGB图像(MJPEG原始数据,完整分辨率1920×1080) - if (!rgbData.isEmpty()) { + if(!rgbData.isEmpty()) { try { // 直接保存JPEG文件(无需解码,保持原始质量) QString rgbPath = QString("%1/%2_rgb.jpg").arg(saveDir).arg(baseName); QFile file(rgbPath); - if (file.open(QIODevice::WriteOnly)) { + if(file.open(QIODevice::WriteOnly)) { file.write(rgbData); file.close(); qDebug() << "保存RGB图像(JPEG):" << rgbPath; @@ -1727,10 +1727,10 @@ bool MainWindow::saveDepthImage(const QString &dir, const QString &baseName, con try { // 转换QImage到OpenCV Mat cv::Mat mat; - if (m_currentImage.format() == QImage::Format_Grayscale8) { + if(m_currentImage.format() == QImage::Format_Grayscale8) { mat = cv::Mat(m_currentImage.height(), m_currentImage.width(), CV_8UC1, const_cast(m_currentImage.bits()), m_currentImage.bytesPerLine()).clone(); - } else if (m_currentImage.format() == QImage::Format_Grayscale16) { + } else if(m_currentImage.format() == QImage::Format_Grayscale16) { mat = cv::Mat(m_currentImage.height(), m_currentImage.width(), CV_16UC1, const_cast(m_currentImage.bits()), m_currentImage.bytesPerLine()).clone(); } else { @@ -1741,11 +1741,11 @@ bool MainWindow::saveDepthImage(const QString &dir, const QString &baseName, con } // 根据format参数保存 - if (format == "png" || format == "both") { + if(format == "png" || format == "both") { // 保存PNG格式(8位) QString pngPath = QString("%1/%2_depth.png").arg(dir).arg(baseName); cv::Mat mat8bit; - if (mat.type() == CV_16UC1) { + if(mat.type() == CV_16UC1) { mat.convertTo(mat8bit, CV_8UC1, 255.0 / 65535.0); } else { mat8bit = mat; @@ -1754,10 +1754,10 @@ bool MainWindow::saveDepthImage(const QString &dir, const QString &baseName, con qDebug() << "保存PNG深度图:" << pngPath; } - if (format == "tiff" || format == "both") { + if(format == "tiff" || format == "both") { // 保存TIFF格式(16位原始数据) QString tiffPath = QString("%1/%2_depth.tiff").arg(dir).arg(baseName); - if (mat.type() == CV_16UC1) { + if(mat.type() == CV_16UC1) { cv::imwrite(tiffPath.toStdString(), mat); qDebug() << "保存TIFF深度图(16位):" << tiffPath; } else { @@ -1779,7 +1779,7 @@ bool MainWindow::saveDepthImage(const QString &dir, const QString &baseName, con bool MainWindow::savePointCloud(const QString &dir, const QString &baseName, const QString &format) { try { - if (!m_currentPointCloud || m_currentPointCloud->empty()) { + if(!m_currentPointCloud || m_currentPointCloud->empty()) { qDebug() << "点云数据为空"; return false; } @@ -1787,10 +1787,10 @@ bool MainWindow::savePointCloud(const QString &dir, const QString &baseName, con bool success = false; // 根据format参数保存 - if (format == "pcd" || format == "both") { + if(format == "pcd" || format == "both") { // 保存PCD格式(PCL标准格式,二进制) QString pcdPath = QString("%1/%2_pointcloud.pcd").arg(dir).arg(baseName); - if (pcl::io::savePCDFileBinary(pcdPath.toStdString(), *m_currentPointCloud) == 0) { + if(pcl::io::savePCDFileBinary(pcdPath.toStdString(), *m_currentPointCloud) == 0) { qDebug() << "保存PCD点云:" << pcdPath; success = true; } else { @@ -1798,10 +1798,10 @@ bool MainWindow::savePointCloud(const QString &dir, const QString &baseName, con } } - if (format == "ply" || format == "both") { + if(format == "ply" || format == "both") { // 保存PLY格式(Polygon格式,ASCII) QString plyPath = QString("%1/%2_pointcloud.ply").arg(dir).arg(baseName); - if (pcl::io::savePLYFileASCII(plyPath.toStdString(), *m_currentPointCloud) == 0) { + if(pcl::io::savePLYFileASCII(plyPath.toStdString(), *m_currentPointCloud) == 0) { qDebug() << "保存PLY点云:" << plyPath; success = true; } else { @@ -1819,18 +1819,18 @@ bool MainWindow::savePointCloud(const QString &dir, const QString &baseName, con // ========== 日志功能 ========== void MainWindow::addLog(const QString &message, const QString &level) { - if (!m_logDisplay) return; + if(!m_logDisplay) return; // 获取当前时间戳 QString timestamp = QDateTime::currentDateTime().toString("HH:mm:ss.zzz"); // 根据日志级别设置颜色 QString color; - if (level == "ERROR") { + if(level == "ERROR") { color = "#FF6B6B"; // 红色 - } else if (level == "WARNING") { + } else if(level == "WARNING") { color = "#FFA500"; // 橙色 - } else if (level == "SUCCESS") { + } else if(level == "SUCCESS") { color = "#4CAF50"; // 绿色 } else { color = "#D4D4D4"; // 默认灰白色 @@ -1851,7 +1851,7 @@ void MainWindow::addLog(const QString &message, const QString &level) // 限制日志行数(保留最近1000行) QTextDocument *doc = m_logDisplay->document(); - if (doc->blockCount() > 1000) { + if(doc->blockCount() > 1000) { QTextCursor cursor = m_logDisplay->textCursor(); cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor, doc->blockCount() - 1000); @@ -1864,7 +1864,7 @@ void MainWindow::addLog(const QString &message, const QString &level) void MainWindow::onClearLogClicked() { - if (m_logDisplay) { + if(m_logDisplay) { m_logDisplay->clear(); addLog("日志已清除", "INFO"); } @@ -1873,11 +1873,11 @@ void MainWindow::onClearLogClicked() void MainWindow::onSaveLogClicked() { QString fileName = QFileDialog::getSaveFileName(this, "保存日志", - QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/d330viewer_log.txt", + QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/viewer_log.txt", "文本文件 (*.txt);;所有文件 (*.*)"); - if (!fileName.isEmpty()) { + if(!fileName.isEmpty()) { QFile file(fileName); - if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { + if(file.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream out(&file); out << m_logDisplay->toPlainText(); file.close(); @@ -1892,23 +1892,23 @@ void MainWindow::onSaveLogClicked() void MainWindow::updateStatistics() { // 更新三个相机的FPS - if (m_leftFpsLabel) { + if(m_leftFpsLabel) { m_leftFpsLabel->setText(QString("左红外: %1 fps").arg(m_currentLeftFps, 0, 'f', 1)); } - if (m_rightFpsLabel) { + if(m_rightFpsLabel) { m_rightFpsLabel->setText(QString("右红外: %1 fps").arg(m_currentRightFps, 0, 'f', 1)); } - if (m_rgbFpsLabel) { + if(m_rgbFpsLabel) { m_rgbFpsLabel->setText(QString("RGB彩色: %1 fps").arg(m_currentRgbFps, 0, 'f', 1)); } // 更新点云帧率 - if (m_pointCloudFpsLabel) { + if(m_pointCloudFpsLabel) { m_pointCloudFpsLabel->setText(QString("点云帧率: %1 fps").arg(m_currentPointCloudFps, 0, 'f', 1)); } // 更新接收帧数(显示三个相机和点云的累计总数) - if (m_queueLabel) { + if(m_queueLabel) { m_queueLabel->setText(QString("接收帧数: L%1 R%2 RGB%3 点云%4") .arg(m_totalLeftFrameCount) .arg(m_totalRightFrameCount) @@ -1920,7 +1920,7 @@ void MainWindow::updateStatistics() // 监听系统主题变化事件 void MainWindow::changeEvent(QEvent *event) { - if (event->type() == QEvent::PaletteChange) { + if(event->type() == QEvent::PaletteChange) { // 系统调色板变化,说明主题可能已切换 qDebug() << "系统主题已变化,刷新UI样式"; diff --git a/src/main.cpp b/src/main.cpp index 81495da..9c4735f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,19 +31,19 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); // 设置应用程序信息 - app.setOrganizationName("D330Viewer"); - app.setApplicationName("D330Viewer"); - app.setApplicationVersion("0.2.0"); + app.setOrganizationName("Viewer"); + app.setApplicationName("Viewer"); + app.setApplicationVersion("0.3.0"); // 初始化Logger(在可执行文件同目录下) - QString logPath = QCoreApplication::applicationDirPath() + "/d330viewer.log"; + QString logPath = QCoreApplication::applicationDirPath() + "/viewer.log"; Logger::instance()->setLogFile(logPath); Logger::instance()->setMaxLines(10000); // 保留最新10000行 // 安装消息处理器 qInstallMessageHandler(messageHandler); - qDebug() << "D330Viewer started"; + qDebug() << "Viewer started"; qDebug() << "Log file:" << logPath; // 创建并显示主窗口 @@ -52,7 +52,7 @@ int main(int argc, char *argv[]) int result = app.exec(); - qDebug() << "D330Viewer exiting"; + qDebug() << "Viewer exiting"; return result; }