GrabBag/GrabBagApp/mainwindow.cpp

814 lines
26 KiB
C++
Raw Normal View History

2025-06-08 12:48:04 +08:00
#include "mainwindow.h"
#include "ui_mainwindow.h"
2025-06-19 01:38:50 +08:00
#include "resultitem.h"
2025-06-08 12:48:04 +08:00
#include <QGraphicsScene>
#include <QStandardItemModel>
#include <QDebug>
#include <QPainter>
#include <QBrush>
#include <QMessageBox>
#include <QFileDialog>
2025-06-19 01:38:50 +08:00
#include <QListWidgetItem>
#include <QtMath>
#include <QThread>
#include <QDateTime>
#include <QTextCursor>
#include <QStringListModel>
#include "VrLog.h"
#include <QIcon>
#include <QMetaType>
#include <QLabel>
#include <QVBoxLayout>
#include "Version.h"
#include "VrSimpleLog.h"
2025-06-08 12:48:04 +08:00
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, m_selectedButton(nullptr)
2025-06-08 12:48:04 +08:00
{
ui->setupUi(this);
// 设置窗口图标
this->setWindowIcon(QIcon(":/resource/logo.png"));
2025-06-08 12:48:04 +08:00
// 设置状态栏字体
QFont statusFont = statusBar()->font();
statusFont.setPointSize(12);
2025-06-08 12:48:04 +08:00
statusBar()->setFont(statusFont);
// 设置状态栏颜色和padding
statusBar()->setStyleSheet("QStatusBar { color: rgb(239, 241, 245); padding: 20px; }");
// 在状态栏右侧添加版本信息(包含编译时间)
// 使用VrSimpleLog.h中的宏定义构建编译时间
QString versionWithBuildTime = QString("%1_%2%3%4%5%6%7")
.arg(GetGrabBagFullVersion())
.arg(YEAR)
.arg(MONTH, 2, 10, QChar('0'))
.arg(DAY, 2, 10, QChar('0'))
.arg(HOUR, 2, 10, QChar('0'))
.arg(MINUTE, 2, 10, QChar('0'))
.arg(SECOND, 2, 10, QChar('0'));
QLabel* buildLabel = new QLabel(versionWithBuildTime);
buildLabel->setStyleSheet("color: rgb(239, 241, 245); font-size: 20px; margin-right: 16px;");
statusBar()->addPermanentWidget(buildLabel);
// 隐藏标题栏
setWindowFlags(Qt::FramelessWindowHint);
// 启动后自动最大化显示
this->showMaximized();
2025-06-08 12:48:04 +08:00
// 初始化时隐藏label_work
ui->label_work->setVisible(false);
ui->detect_image_2->setVisible(false);
2025-06-08 12:48:04 +08:00
// 初始化GraphicsScene
QGraphicsScene* scene = new QGraphicsScene(this);
ui->detect_image->setScene(scene);
// 为第二个图像视图初始化GraphicsScene
QGraphicsScene* scene2 = new QGraphicsScene(this);
ui->detect_image_2->setScene(scene2);
2025-06-19 01:38:50 +08:00
// 初始化日志模型
m_logModel = new QStringListModel(this);
ui->detect_log->setModel(m_logModel);
2025-06-08 12:48:04 +08:00
2025-06-19 01:38:50 +08:00
// 原有的状态指示器已删除状态显示统一在devstatus中处理
// 注册自定义类型,使其能够在信号槽中跨线程传递
qRegisterMetaType<DetectionResult>("DetectionResult");
qRegisterMetaType<WorkStatus>("WorkStatus");
qRegisterMetaType<GrabBagPosition>("GrabBagPosition");
// 连接工作状态更新信号槽
connect(this, &MainWindow::workStatusUpdateRequested, this, &MainWindow::updateWorkStatusLabel);
// 连接检测结果更新信号槽
connect(this, &MainWindow::detectionResultUpdateRequested, this, &MainWindow::updateDetectionResultDisplay);
2025-06-08 12:48:04 +08:00
2025-06-19 01:38:50 +08:00
// 连接日志更新信号槽
connect(this, &MainWindow::logUpdateRequested, this, &MainWindow::updateDetectionLog);
// 连接清空日志信号槽
connect(this, &MainWindow::logClearRequested, this, &MainWindow::clearDetectionLogUI);
updateStatusLog(tr("设备开始初始化..."));
2025-06-08 12:48:04 +08:00
2025-06-08 12:48:04 +08:00
// 初始化模块
Init();
}
MainWindow::~MainWindow()
{
// 释放业务逻辑处理类
if (m_presenter) {
delete m_presenter;
m_presenter = nullptr;
}
delete ui;
}
void MainWindow::updateStatusLog(const QString& message)
{
2025-06-19 01:38:50 +08:00
// 更新状态栏
// statusBar()->showMessage(message);
// 通过信号槽机制更新detect_log控件
emit logUpdateRequested(message);
}
void MainWindow::clearDetectionLog()
{
// 通过信号槽机制清空日志
emit logClearRequested();
2025-06-08 12:48:04 +08:00
}
void MainWindow::Init()
{
// 创建业务逻辑处理类
m_presenter = new GrabBagPresenter();
// 设置状态回调接口
m_presenter->SetStatusCallback(this);
2025-06-19 01:38:50 +08:00
m_deviceStatusWidget = new devstatus(); //因为初始化回调的数据要存储所以要在init前创建好
// 将设备状态widget添加到frame_dev中
QVBoxLayout* frameDevLayout = new QVBoxLayout(ui->frame_dev);
frameDevLayout->setContentsMargins(0, 0, 0, 0);
frameDevLayout->addWidget(m_deviceStatusWidget);
2025-06-19 01:38:50 +08:00
// 设置列表视图模式
ui->detect_result_list->setViewMode(QListView::IconMode);
ui->detect_result_list->setResizeMode(QListView::Adjust);
ui->detect_result_list->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
2025-06-19 01:38:50 +08:00
ui->detect_result_list->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
#if 0
// 完全禁用拖拽和移动功能
ui->detect_result_list->setDragDropMode(QAbstractItemView::NoDragDrop);
ui->detect_result_list->setDragEnabled(false);
ui->detect_result_list->setAcceptDrops(false);
ui->detect_result_list->setDefaultDropAction(Qt::IgnoreAction);
ui->detect_result_list->setMovement(QListView::Static); // 禁止项目移动
// 设置选择模式但禁用多选
ui->detect_result_list->setSelectionMode(QAbstractItemView::SingleSelection);
ui->detect_result_list->setSelectionBehavior(QAbstractItemView::SelectItems);
// 确保滚动功能正常工作
ui->detect_result_list->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
ui->detect_result_list->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
#endif
// 初始化期间禁用所有功能按钮
setButtonsEnabled(false);
// 在线程中执行初始化业务逻辑
std::thread initThread([this]() {
updateStatusLog(tr("正在初始化系统..."));
int result = m_presenter->Init();
if (result != 0) {
updateStatusLog(tr("初始化失败,错误码:%1").arg(result));
} else {
updateStatusLog(tr("系统初始化完成"));
}
});
// 分离线程,让其在后台运行
initThread.detach();
2025-06-08 12:48:04 +08:00
}
void MainWindow::displayImage(const QImage& image)
{
if (image.isNull()) {
updateStatusLog(tr("图片无效"));
return;
}
QGraphicsScene* scene = ui->detect_image->scene();
scene->clear();
QPixmap pixmap = QPixmap::fromImage(image);
scene->addPixmap(pixmap);
ui->detect_image->fitInView(scene->sceneRect(), Qt::KeepAspectRatio);
}
// 在第二个图像视图中显示图像
void MainWindow::displayImageInSecondView(const QImage& image)
{
if (image.isNull()) {
updateStatusLog(tr("第二相机图片无效"));
return;
}
QGraphicsScene* scene2 = ui->detect_image_2->scene();
scene2->clear();
QPixmap pixmap = QPixmap::fromImage(image);
scene2->addPixmap(pixmap);
ui->detect_image_2->fitInView(scene2->sceneRect(), Qt::KeepAspectRatio);
}
2025-06-08 12:48:04 +08:00
// 添加扩展版本的检测结果函数
void MainWindow::addDetectionResult(const DetectionResult& result)
{
// 清空之前的所有检测结果数据
ui->detect_result_list->clear();
2025-06-19 01:38:50 +08:00
// 设置item间距和流向gridSize现在在布局调整函数中动态设置
int itemSpacing = 0;
ui->detect_result_list->setSpacing(itemSpacing); // 设置item间距为0px
2025-06-19 01:38:50 +08:00
// 获取当前的gridSize由布局调整函数设置
QSize currentGridSize = ui->detect_result_list->gridSize();
int gridWidth = currentGridSize.width();
int gridHeight = currentGridSize.height();
2025-06-19 01:38:50 +08:00
int targetIndex = 1;
for (const auto& position : result.positions) {
// 创建自定义的ResultItem widget
ResultItem* resultWidget = new ResultItem();
// 设置widget的autoFillBackground属性确保背景色生效
resultWidget->setAutoFillBackground(true);
// 设置检测结果数据直接使用GrabBagPosition
resultWidget->setResultData(targetIndex, position);
// 创建QListWidgetItem
QListWidgetItem* item = new QListWidgetItem();
// 设置item背景为透明让自定义widget的背景显示出来
item->setBackground(QBrush(Qt::transparent));
// 设置item的大小提示 - 应该与gridSize一致
item->setSizeHint(QSize(gridWidth, gridHeight));
// 确保每个item都不能被拖动
item->setFlags(item->flags() & ~Qt::ItemIsDragEnabled & ~Qt::ItemIsDropEnabled);
// 将item添加到列表
ui->detect_result_list->addItem(item);
// 将自定义widget设置为item的显示内容
ui->detect_result_list->setItemWidget(item, resultWidget);
targetIndex++;
2025-06-19 01:38:50 +08:00
}
2025-06-08 12:48:04 +08:00
}
// 状态更新槽函数
void MainWindow::OnStatusUpdate(const std::string& statusMessage)
{
2025-06-19 01:38:50 +08:00
LOG_DEBUG("[UI Display] Status update: %s\n", statusMessage.c_str());
2025-06-08 12:48:04 +08:00
updateStatusLog(QString::fromStdString(statusMessage));
}
void MainWindow::OnDetectionResult(const DetectionResult& result)
{
// 通过信号槽机制更新UI确保在主线程中执行
emit detectionResultUpdateRequested(result);
2025-06-08 12:48:04 +08:00
}
void MainWindow::OnCamera1StatusChanged(bool isConnected)
{
2025-06-19 01:38:50 +08:00
// 直接更新设备状态widget
if (m_deviceStatusWidget) {
m_deviceStatusWidget->updateCamera1Status(isConnected);
}
2025-06-08 12:48:04 +08:00
}
// 相机2状态更新槽函数
void MainWindow::OnCamera2StatusChanged(bool isConnected)
{
2025-06-19 01:38:50 +08:00
// 直接更新设备状态widget
if (m_deviceStatusWidget) {
m_deviceStatusWidget->updateCamera2Status(isConnected);
}
2025-06-08 12:48:04 +08:00
}
// 相机个数更新槽函数
void MainWindow::OnCameraCountChanged(int cameraCount)
{
2025-06-19 01:38:50 +08:00
// 设置设备状态widget中的相机数量
if (m_deviceStatusWidget) {
m_deviceStatusWidget->setCameraCount(cameraCount);
}
// 根据相机个数调整页面布局
adjustLayoutForCameraCount(cameraCount);
2025-06-19 01:38:50 +08:00
// 如果只有一个相机,更新状态消息
2025-06-08 12:48:04 +08:00
if (cameraCount < 2) {
// 更新状态消息
updateStatusLog(tr("系统使用单相机模式"));
} else {
// 更新状态消息
updateStatusLog(tr("系统使用双相机模式"));
}
}
// 机械臂状态更新槽函数
void MainWindow::OnRobotConnectionChanged(bool isConnected)
{
2025-06-19 01:38:50 +08:00
// 直接更新设备状态widget
if (m_deviceStatusWidget) {
m_deviceStatusWidget->updateRobotStatus(isConnected);
}
2025-06-08 12:48:04 +08:00
}
// 工作状态更新槽函数
void MainWindow::OnWorkStatusChanged(WorkStatus status)
{
// 通过信号槽机制更新UI确保在主线程中执行
emit workStatusUpdateRequested(status);
}
void MainWindow::updateWorkStatusLabel(WorkStatus status)
2025-06-08 12:48:04 +08:00
{
2025-06-19 01:38:50 +08:00
// 如果状态变为Working清空检测日志表示开始新的检测
if (status == WorkStatus::Working) {
clearDetectionLog();
}
2025-06-08 12:48:04 +08:00
// 获取状态对应的显示文本
QString statusText = QString::fromStdString(WorkStatusToString(status));
// 在label_work中显示状态
if (!ui->label_work) return;
ui->label_work->setText(statusText);
// 根据不同状态设置不同的样式和按钮启用状态
switch (status) {
case WorkStatus::Ready:
ui->label_work->setStyleSheet("color: green;");
setButtonsEnabled(true); // 就绪状态下启用所有按钮
break;
case WorkStatus::InitIng:
ui->label_work->setStyleSheet("color: blue;");
setButtonsEnabled(false); // 初始化期间禁用按钮
break;
case WorkStatus::Working:
ui->label_work->setStyleSheet("color: blue;");
setButtonsEnabled(false); // 工作期间禁用按钮
break;
case WorkStatus::Completed:
ui->label_work->setStyleSheet("color: green; font-weight: bold;");
setButtonsEnabled(true); // 完成后启用按钮
break;
case WorkStatus::Error:
ui->label_work->setStyleSheet("color: red; font-weight: bold;");
setButtonsEnabled(true); // 错误状态下仍可操作
break;
default:
ui->label_work->setStyleSheet("");
setButtonsEnabled(false); // 未知状态禁用按钮
break;
2025-06-08 12:48:04 +08:00
}
}
void MainWindow::updateDetectionResultDisplay(const DetectionResult& result)
{
// 根据相机索引决定显示在哪个图像视图上
if (result.cameraIndex == 2) {
// 第二个相机的结果显示在detect_image_2上
updateDetectionLog(tr("相机2检测结果图像更新"));
displayImageInSecondView(result.image);
} else {
// 第一个相机或默认显示在detect_image上
updateDetectionLog(tr("相机1检测结果图像更新"));
displayImage(result.image);
}
// 更新检测结果到列表
updateDetectionLog(tr("检测结果列表更新"));
addDetectionResult(result);
}
void MainWindow::updateDetectionLog(const QString& message)
{
// 在UI线程中更新detect_log控件QListView
if (!m_logModel) return ;
// 添加时间戳(包含年月日)
QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
QString logEntry = QString("[%1] %2").arg(timestamp).arg(message);
// 获取当前数据
QStringList logList = m_logModel->stringList();
// 添加新的日志条目
logList.append(logEntry);
// 更新模型
m_logModel->setStringList(logList);
// 自动滚动到最底部
QModelIndex lastIndex = m_logModel->index(logList.size() - 1);
ui->detect_log->scrollTo(lastIndex);
}
void MainWindow::clearDetectionLogUI()
{
// 在UI线程中清空检测日志
if (m_logModel) {
m_logModel->setStringList(QStringList());
}
}
2025-06-08 12:48:04 +08:00
void MainWindow::on_btn_start_clicked()
{
// 检查Presenter是否已初始化
if (!m_presenter) {
updateStatusLog(tr("系统未初始化,请等待初始化完成"));
return;
}
// 清空检测日志,开始新的检测
clearDetectionLog();
// 使用Presenter启动检测
m_presenter->StartDetection(1, false);
}
void MainWindow::on_btn_stop_clicked()
{
// 检查Presenter是否已初始化
if (!m_presenter) {
updateStatusLog(tr("系统未初始化,请等待初始化完成"));
return;
}
m_presenter->StopDetection();
}
void MainWindow::on_btn_camera_clicked()
{
// 检查是否有其他按钮已被选中
if (m_selectedButton != nullptr && m_selectedButton != ui->btn_camera) {
updateStatusLog(tr("请先关闭当前打开的配置窗口"));
return;
}
// 检查Presenter是否已初始化
if (!m_presenter) {
updateStatusLog(tr("系统未初始化,请等待初始化完成"));
return;
}
// 设置当前按钮为选中状态
setButtonSelectedState(ui->btn_camera, true);
// 使用新的相机列表获取功能
std::vector<IVrEyeDevice*> availableCameras;
std::vector<QString> cameraNames;
// 获取相机列表和名称
m_presenter->GetCameraListWithNames(availableCameras, cameraNames);
// 如果对话框不存在创建新的DialogCamera
if (nullptr == ui_dialogCamera) {
ui_dialogCamera = new DialogCamera(availableCameras, cameraNames, this);
// 连接对话框关闭信号
connect(ui_dialogCamera, &QDialog::finished, this, [this]() {
setButtonSelectedState(ui->btn_camera, false);
});
}
ui_dialogCamera->show();
}
void MainWindow::on_btn_algo_config_clicked()
{
// 检查是否有其他按钮已被选中
if (m_selectedButton != nullptr && m_selectedButton != ui->btn_algo_config) {
updateStatusLog(tr("请先关闭当前打开的配置窗口"));
return;
}
// 检查Presenter是否已初始化
if (!m_presenter) {
updateStatusLog(tr("系统未初始化,请等待初始化完成"));
return;
}
// 设置当前按钮为选中状态
setButtonSelectedState(ui->btn_algo_config, true);
// 获取配置对象
IVrConfig* config = m_presenter->GetConfig();
if (!config) {
// 恢复按钮状态
setButtonSelectedState(ui->btn_algo_config, false);
// 设置白色字体的警告消息框
QMessageBox msgBox;
msgBox.setWindowTitle("错误");
msgBox.setText("配置模块未正确初始化!");
msgBox.setIcon(QMessageBox::Warning);
msgBox.setStyleSheet("QMessageBox { color: white; }");
msgBox.exec();
return;
}
if(nullptr == ui_dialogConfig){
ui_dialogConfig = new DialogConfig(config, this);
// 连接对话框关闭信号
connect(ui_dialogConfig, &QDialog::finished, this, [this]() {
setButtonSelectedState(ui->btn_algo_config, false);
});
}
ui_dialogConfig->show();
}
void MainWindow::on_btn_camera_levelling_clicked()
{
// 检查是否有其他按钮已被选中
if (m_selectedButton != nullptr && m_selectedButton != ui->btn_camera_levelling) {
updateStatusLog(tr("请先关闭当前打开的配置窗口"));
return;
}
// 检查Presenter是否已初始化
if (!m_presenter) {
updateStatusLog(tr("系统未初始化,请等待初始化完成"));
return;
}
// 设置当前按钮为选中状态
setButtonSelectedState(ui->btn_camera_levelling, true);
if(nullptr == ui_dialogCameraLevel){
ui_dialogCameraLevel = new DialogCameraLevel(this);
// 连接对话框关闭信号
connect(ui_dialogCameraLevel, &QDialog::finished, this, [this]() {
setButtonSelectedState(ui->btn_camera_levelling, false);
});
}
// 获取相机列表和名称
std::vector<IVrEyeDevice*> availableCameras;
std::vector<QString> cameraNames;
m_presenter->GetCameraListWithNames(availableCameras, cameraNames);
// 设置相机列表和presenter到对话框
ui_dialogCameraLevel->setCameraList(availableCameras, cameraNames, m_presenter);
ui_dialogCameraLevel->show();
}
void MainWindow::on_btn_hide_clicked()
{
// 最小化窗口
this->showMinimized();
}
void MainWindow::on_btn_close_clicked()
{
// 关闭应用程序
this->close();
}
void MainWindow::on_btn_test_clicked()
{
// 检查是否有其他按钮已被选中
if (m_selectedButton != nullptr && m_selectedButton != ui->btn_test) {
updateStatusLog(tr("请先关闭当前打开的配置窗口"));
return;
}
// 设置当前按钮为选中状态
setButtonSelectedState(ui->btn_test, true);
// 打开文件选择对话框
QString fileName = QFileDialog::getOpenFileName(
this,
tr("选择调试数据文件"),
QString(),
tr("激光数据文件 (*.txt);;所有文件 (*.*)")
);
if (fileName.isEmpty()) {
// 用户取消了文件选择,恢复按钮状态
setButtonSelectedState(ui->btn_test, false);
return;
}
// 检查Presenter是否已初始化
if (!m_presenter) {
// 恢复按钮状态
setButtonSelectedState(ui->btn_test, false);
QMessageBox::warning(this, tr("错误"), tr("系统未正确初始化!"));
return;
}
2025-06-19 01:38:50 +08:00
// 清空检测日志,开始新的检测
clearDetectionLog();
std::thread t([this, fileName]() {
int result = m_presenter->LoadDebugDataAndDetect(fileName.toStdString());
if (result == 0) {
updateStatusLog(tr("调试数据加载和检测成功"));
} else {
QString errorMsg = tr("调试数据加载失败,错误码: %1").arg(result);
updateStatusLog(errorMsg);
QMessageBox::warning(this, tr("错误"), errorMsg);
}
// 测试完成后恢复按钮状态
QMetaObject::invokeMethod(this, [this]() {
setButtonSelectedState(ui->btn_test, false);
}, Qt::QueuedConnection);
});
t.detach();
}
2025-06-08 12:48:04 +08:00
// 设置按钮启用/禁用状态
void MainWindow::setButtonsEnabled(bool enabled)
{
// 功能按钮
if (ui->btn_start) ui->btn_start->setEnabled(enabled);
if (ui->btn_stop) ui->btn_stop->setEnabled(enabled);
if (ui->btn_camera) ui->btn_camera->setEnabled(enabled);
if (ui->btn_algo_config) ui->btn_algo_config->setEnabled(enabled);
if (ui->btn_camera_levelling) ui->btn_camera_levelling->setEnabled(enabled);
// if (ui->btn_test) ui->btn_test->setEnabled(enabled);
// 窗口控制按钮(最小化和关闭)始终可用
// if (ui->btn_hide) ui->btn_hide->setEnabled(true);
// if (ui->btn_close) ui->btn_close->setEnabled(true);
}
// 设置按钮图像
void MainWindow::setButtonImage(QPushButton* button, const QString& imagePath)
{
if (button) {
QString styleSheet = QString("image: url(%1);").arg(imagePath);
button->setStyleSheet(styleSheet);
}
}
// 设置按钮选中状态
void MainWindow::setButtonSelectedState(QPushButton* button, bool selected)
{
if (!button) return;
QString normalImage, selectedImage;
// 根据按钮确定对应的图像路径
if (button == ui->btn_camera) {
normalImage = ":/resource/config_camera.png";
selectedImage = ":/resource/config_camera_s.png";
} else if (button == ui->btn_algo_config) {
normalImage = ":/resource/config_algo.png";
selectedImage = ":/resource/config_algo_s.png";
} else if (button == ui->btn_camera_levelling) {
normalImage = ":/resource/config_camera_level.png";
selectedImage = ":/resource/config_camera_level_s.png";
} else if (button == ui->btn_test) {
normalImage = ":/resource/config_data_test.png";
selectedImage = ":/resource/config_data_test_s.png";
}
// 设置对应的图像
if (selected) {
setButtonImage(button, selectedImage);
m_selectedButton = button;
// 禁用其他按钮
setOtherButtonsEnabled(button, false);
} else {
setButtonImage(button, normalImage);
if (m_selectedButton == button) {
m_selectedButton = nullptr;
// 启用所有按钮
setOtherButtonsEnabled(nullptr, true);
}
}
}
// 恢复所有按钮状态
void MainWindow::restoreAllButtonStates()
{
setButtonSelectedState(ui->btn_camera, false);
setButtonSelectedState(ui->btn_algo_config, false);
setButtonSelectedState(ui->btn_camera_levelling, false);
setButtonSelectedState(ui->btn_test, false);
}
// 设置其他按钮的启用状态(用于互斥控制)
void MainWindow::setOtherButtonsEnabled(QPushButton* exceptButton, bool enabled)
{
QList<QPushButton*> configButtons = {
ui->btn_camera,
ui->btn_algo_config,
ui->btn_camera_levelling,
ui->btn_test
};
for (QPushButton* button : configButtons) {
if (button && button != exceptButton) {
button->setEnabled(enabled);
}
}
}
// 根据相机个数调整页面布局
void MainWindow::adjustLayoutForCameraCount(int cameraCount)
{
if (cameraCount <= 1) {
// 单相机模式布局
setupSingleCameraLayout();
} else {
// 多相机模式布局
setupMultiCameraLayout();
}
}
// 设置单相机模式布局
void MainWindow::setupSingleCameraLayout()
{
// 单相机模式下的原始布局
// detect_image: 占据左侧大部分空间
ui->detect_image->setGeometry(20, 140, 1311, 890);
// detect_image_2: 隐藏
ui->detect_image_2->setVisible(false);
// 设备状态框架: 位于右上方,恢复原始尺寸
ui->frame_dev->setGeometry(1344, 140, 556, 64);
// 检测结果列表: 位于右侧中间
ui->detect_result_list->setGeometry(1344, 216, 556, 622);
// 单相机模式下恢复原有的垂直滚动设置
ui->detect_result_list->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->detect_result_list->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->detect_result_list->setFlow(QListView::LeftToRight); // 从左到右排列
ui->detect_result_list->setWrapping(true); // 允许换行
// 单相机模式设置gridSizegridHeight = 207
int gridWidth = 275;
int gridHeight = 206;
ui->detect_result_list->setGridSize(QSize(gridWidth, gridHeight));
// 恢复设备状态widget的原始布局
m_deviceStatusWidget->setCameraCount(1);
// 日志: 位于右下方
ui->detect_log->setGeometry(1344, 852, 556, 178);
updateStatusLog(tr("页面布局已调整为单相机模式"));
}
// 设置多相机模式布局
void MainWindow::setupMultiCameraLayout()
{
// 多相机模式下的布局调整
// detect_image: 缩小到左侧一半空间
ui->detect_image->setGeometry(20, 140, 934, 660);
// detect_image_2: 显示在右侧一半空间
ui->detect_image_2->setVisible(true);
ui->detect_image_2->setGeometry(964, 140, 934, 660);
// 设备状态框架: 移动到下方左侧,调整为更高的尺寸以适应纵向排布
ui->frame_dev->setGeometry(20, 806, 180, 198);
// 检测结果列表: 移动到下方中间
ui->detect_result_list->setGeometry(206, 806, 1380, 220);
// 多相机模式下设置detect_result_list为横向滚动
ui->detect_result_list->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->detect_result_list->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
ui->detect_result_list->setFlow(QListView::LeftToRight); // 改为从上到下排列
ui->detect_result_list->setWrapping(false); // 禁用换行,实现横向滚动
// 多相机模式设置gridSizegridHeight = 200
int gridWidth = 230;
int gridHeight = 190;
ui->detect_result_list->setGridSize(QSize(gridWidth, gridHeight));
m_deviceStatusWidget->setCameraCount(2);
// 日志: 移动到下方右侧
ui->detect_log->setGeometry(1592, 806, 308, 198);
updateStatusLog(tr("页面布局已调整为多相机模式"));
}