Files
HPPA/HPPA/HPPA.cpp
2026-03-12 16:51:13 +08:00

2155 lines
68 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "stdafx.h"
//#include <afx.h>
#include <exception>
#include <QMessageBox>
#include <QFileInfo> // 新增,用于解析路径
#include "HPPA.h"
#include "RasterLayer.h"
#include "LayerTreeLayerNode.h"
#include "MapTool.h"
#include "MapToolPan.h"
#include "MapToolSpectral.h"
#include "MapTools.h"
HPPA* HPPA::s_instance = nullptr;
HPPA* HPPA::instance()
{
return s_instance;
}
LayerTreeNode* HPPA::rasterGroupNode() const
{
return m_RasterGroup;
}
HPPA::HPPA(QWidget* parent)
: QMainWindow(parent)
{
s_instance = this;
ui.setupUi(this);
// register MapLayer* metatype for queued signal/slot across threads
qRegisterMetaType<MapLayer*>("MapLayer*");
QCoreApplication::setOrganizationName("IRIS");
QCoreApplication::setOrganizationDomain("iris.com");
QCoreApplication::setApplicationName("HPPA");
//配置文件:如果没有,就创建配置文件
string HPPACfgFile = getPathofEXE() + "\\HPPA.cfg";
mConfigfile.setConfigfilePath(HPPACfgFile);
if (!mConfigfile.isConfigfileExist())
{
mConfigfile.createConfigFile();
qDebug() << "create: " << QString::fromStdString(HPPACfgFile);
}
mConfigfile.parseConfigfile();
qDebug() << "exist: " << QString::fromStdString(HPPACfgFile);
// Create MapLayerStore early so created layers are managed
m_MapLayerStore = new MapLayerStore(this);
/*int max, min;
mConfigfile.getPositionRestriction(max, min);
string sn;
mConfigfile.getSN(sn);
int coarse, fine;
mConfigfile.getTuningStepSize(coarse, fine);
float fa, fb;
mConfigfile.getFitParams(fa, fb);
int max_FocusRange, min_FocusRange;
mConfigfile.getAutoFocusRange(max_FocusRange, min_FocusRange);
float StepAnglemar_x, Lead_x, ScaleFactor_x;
int SubdivisionMultiples_x;
mConfigfile.getXMotorParm(StepAnglemar_x, Lead_x, SubdivisionMultiples_x, ScaleFactor_x);
float StepAnglemar_y, Lead_y, ScaleFactor_y;
int SubdivisionMultiples_y;
mConfigfile.getYMotorParm(StepAnglemar_y, Lead_y, SubdivisionMultiples_y, ScaleFactor_y);*/
//状态栏
//xmotor_state_label1 = new QLabel();
//ymotor_state_label1 = new QLabel();
//xmotor_state_label1->setText("xMotor");
//ymotor_state_label1->setText("yMotor");
//ui.statusBar->addPermanentWidget(xmotor_state_label1);
//ui.statusBar->addPermanentWidget(ymotor_state_label1);
connect(this->ui.action_exit, SIGNAL(triggered()), this, SLOT(onExit()));
connect(this->ui.mActionOpenImg, SIGNAL(triggered()), this, SLOT(onOpenImg()));
//ui.cam_label->setScaledContents(true);
/*ui.splitter->setStretchFactor(0, 1);
ui.splitter->setStretchFactor(1, 1);
ui.splitter->setStretchFactor(2, 3);*/
initMenubarToolbar();
initMapTools();
//光谱仪操作
m_Imager = nullptr;
m_RecordState = 0;
connect(this->ui.action_connect_imager, SIGNAL(triggered()), this, SLOT(onconnect()));//信号与槽连接相机相机操作相关信号与槽绑定放在函数onconnect中
//设置相机可用帧率范围这些设置必须在slider的信号和槽连接connect前否则setMinimum会改变slider的值
ui.FramerateSlider->setMinimum(1);
ui.FramerateSlider->setMaximum(250);
ui.GainSlider->setMinimum(0);
ui.GainSlider->setMaximum(24);
//相机参数控件设置为不可用
frame_number->setEnabled(false);
ui.framerate_lineEdit->setEnabled(false);
ui.integratioin_time_lineEdit->setEnabled(false);
ui.gain_lineEdit->setEnabled(false);
ui.FramerateSlider->setEnabled(false);
ui.IntegratioinTimeSlider->setEnabled(false);
ui.GainSlider->setEnabled(false);
startTimer(1000);
widthScale = 1;
heightScale = 1;
//马达位置模拟
//connect(ui.graphicsView->imager, SIGNAL(leftMouseButtonPressed(int, int)), this, SLOT(onimagerSimulatorMove(int, int)));
initPanelToolbar();
initMapTools();
setDockNestingEnabled(true);
connect(this->ui.action_about, SIGNAL(triggered()), this, SLOT(onAbout()));
connect(this->ui.mActionOneMotorScenario, SIGNAL(triggered()), this, SLOT(createOneMotorScenario()));
connect(this->ui.mActionPlantPhenotypeScenario, SIGNAL(triggered()), this, SLOT(createPlantPhenotypeScenario()));
delete ui.centralWidget;
QString qss_DockWidget_contentWidget = R"(
background: #0D1233;
/*border: 1px solid #2c586b;*/
border-top: 1px solid #2c586b;
border-left: 1px solid #2c586b;
border-right: 1px solid #2c586b;
border-bottom: 1px solid #2c586b;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
)";
//TOC
CustomDockWidgetBase* dock_layers = new CustomDockWidgetBase(QString::fromLocal8Bit("layers"), this);
dock_layers->setObjectName("mDockLayers");
dock_layers->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
mPanelMenu->addAction(dock_layers->toggleViewAction());
addDockWidget(Qt::LeftDockWidgetArea, dock_layers);
dock_layers->hideMaxButton();
//1、没用
QWidget* dock_layersWidgetContents = new QWidget();
dock_layersWidgetContents->setObjectName(QString::fromUtf8("dockWidgetContents_2"));
QGridLayout* gridLayout_toc = new QGridLayout(dock_layersWidgetContents);
gridLayout_toc->setSpacing(6);
gridLayout_toc->setContentsMargins(11, 11, 11, 11);
gridLayout_toc->setObjectName(QString::fromUtf8("gridLayout_toc"));
gridLayout_toc->setVerticalSpacing(0);
gridLayout_toc->setContentsMargins(0, 0, 0, 0);
ImagerPositionSimulation* graphicsView_delete = new ImagerPositionSimulation(dock_layersWidgetContents);
graphicsView_delete->setObjectName(QString::fromUtf8("graphicsView_delete"));
QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Preferred);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
sizePolicy1.setHeightForWidth(graphicsView_delete->sizePolicy().hasHeightForWidth());
graphicsView_delete->setSizePolicy(sizePolicy1);
graphicsView_delete->setFrameShape(QFrame::NoFrame);
graphicsView_delete->setFrameShadow(QFrame::Raised);
//gridLayout_toc->addWidget(graphicsView_delete, 0, 0, 1, 1);
//2、没用仅仅使用QTreeWidget实现的简略ui
QTreeWidget* treeWidget = new QTreeWidget();
treeWidget->setColumnCount(1);
treeWidget->setIndentation(18);
treeWidget->setRootIsDecorated(true);
treeWidget->header()->hide();
treeWidget->setStyleSheet(R"(
QTreeWidget
{
color: #ACCDFF;
}
QTreeWidget::branch {
background: transparent;
}
QTreeWidget::branch:has-children:!has-siblings:closed,
QTreeWidget::branch:closed:has-children:has-siblings
{
border-image: none;
image: url(D:/cpp_project_vs2022/HPPA/x64/Debug/3DModel/tree_tri_right.svg);
}
QTreeWidget::branch:open:has-children:!has-siblings,
QTreeWidget::branch:open:has-children:has-siblings
{
border-image: none;
image: url(D:/cpp_project_vs2022/HPPA/x64/Debug/3DModel/tree_tri_down.svg);
}
)");
//QList<QTreeWidgetItem*> items;
//for (int i = 0; i < 3; ++i)
// items.append(new QTreeWidgetItem((QTreeWidget*)0, QStringList(QString("tmp_image_%1").arg(i))));
//treeWidget->insertTopLevelItems(0, items);
QTreeWidgetItem* group1 = new QTreeWidgetItem(treeWidget);
group1->setText(0, "Raster");
group1->setExpanded(true); // 默认展开
QTreeWidgetItem* group2 = new QTreeWidgetItem(treeWidget);
group2->setText(0, "Vector");
group2->setExpanded(true);
QTreeWidgetItem* layerA = new QTreeWidgetItem(group1);
layerA->setText(0, "tmp_image_1");
QTreeWidgetItem* layerB = new QTreeWidgetItem(group1);
layerB->setText(0, "tmp_image_2");
//gridLayout_toc->addWidget(treeWidget, 0, 0, 1, 1);
//3、正经TOC
m_LayerTree = new LayerTree();
m_LayerTreeModel = new LayerTreeModel(m_LayerTree, this, true);
// 创建并保留 Raster 分组指针,后续添加 layer 使用它
m_RasterGroup = m_LayerTreeModel->addGroup(m_LayerTreeModel->root(), "Raster");
//{
// auto* ln1 = new LayerTreeLayerNode(nullptr);
// ln1->setName("tmp_image_1");
// m_LayerTreeModel->addLayer(m_RasterGroup, ln1);
//}
//{
// auto* ln2 = new LayerTreeLayerNode(nullptr);
// ln2->setName("tmp_image_2");
// m_LayerTreeModel->addLayer(m_RasterGroup, ln2);
//}
auto* g2 = m_LayerTreeModel->addGroup(m_LayerTreeModel->root(), "Vector");
//model->addLayer(g2, "Rivers");
m_layerTreeView = new LayerTreeView();
m_layerTreeView->setMenuProvider(new LayerTreeViewMenuProvider(m_layerTreeView));
m_layerTreeView->setModel(m_LayerTreeModel);
m_layerTreeView->setHeaderHidden(true);
m_layerTreeView->setStyleSheet(R"(
QTreeView
{
color: #ACCDFF;
}
QTreeView::branch {
background: transparent;
}
QTreeView::branch:has-children:!has-siblings:closed,
QTreeView::branch:closed:has-children:has-siblings
{
border-image: none;
image: url(D:/cpp_project_vs2022/HPPA/x64/Debug/3DModel/tree_tri_right.svg);
}
QTreeView::branch:open:has-children:!has-siblings,
QTreeView::branch:open:has-children:has-siblings
{
border-image: none;
image: url(D:/cpp_project_vs2022/HPPA/x64/Debug/3DModel/tree_tri_down.svg);
}
)");
gridLayout_toc->addWidget(m_layerTreeView, 0, 0, 1, 1);
// Connect TOC selection change to populate ImageControl
connect(m_layerTreeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
this, SLOT(onLayerTreeSelectionChanged(QItemSelection,QItemSelection)));
dock_layers->setWidget(dock_layersWidgetContents);
dock_layersWidgetContents->setStyleSheet(qss_DockWidget_contentWidget);
//dock_layers->setMinimumWidth(449);
//dock_layers->setMaximumWidth(450);
//dock_layers->setMinimumHeight(497);
//dock_layers->setMaximumHeight(498);
//高光谱查看
QDockWidget* dock_hyperimgViewer = new CustomDockWidgetBase(QString::fromLocal8Bit("hyimgViewer"), this);
dock_hyperimgViewer->setObjectName("hyimgViewer");
QWidget* dock_hyperimgViewerWidgetContents = new QWidget();
dock_hyperimgViewerWidgetContents->setObjectName(QString::fromUtf8("dock_hyperimgViewerWidgetContents"));
QGridLayout* gridLayout_hyperimgViewer = new QGridLayout(dock_hyperimgViewerWidgetContents);
gridLayout_hyperimgViewer->setSpacing(6);
gridLayout_hyperimgViewer->setObjectName(QString::fromUtf8("gridLayout_hyperimgViewer"));
gridLayout_hyperimgViewer->setVerticalSpacing(6);
gridLayout_hyperimgViewer->setContentsMargins(1, 2, 1, 2);
m_imageViewerTabWidget = new QTabWidget();
//m_imageViewerTabWidget->tabBar()->setFixedHeight(40);//没有效果在qss中设置高度才有效果为啥
m_imageViewerTabWidget->clear();//必须放在最前面首先删除所有的tab
QToolButton* maxButton = new QToolButton();
maxButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarMaxButton));
connect(maxButton, SIGNAL(clicked()), dock_hyperimgViewer, SLOT(toggleMaximize()));
m_imageViewerTabWidget->setCornerWidget(maxButton, Qt::TopRightCorner);
//onCreateTab(0);
//m_imageViewerTabWidget->setTabsClosable(true);//这样每页都会有关闭按钮
connect(m_imageViewerTabWidget, SIGNAL(currentChanged(int)), this, SLOT(onTabWidgetCurrentChanged(int)));
m_imageViewerTabWidget->setStyleSheet(R"(
QTabBar::tab {
background: #0E1C4C;
color: white;
padding: 6px 12px;
border: none;
border-bottom: 1px solid #27376C;
height: 18;
}
QTabBar::tab:selected {
background: #0D1233;
color: white;
border: none;
}
/*QTabBar::tab:hover {
background: #141A45;
}*/
QTabWidget::pane {
border: none;
border-top: 1px solid #27376C;
background: #0D1233;
top: -1px;
}
QTabWidget QWidget {
background: #0D1233;
}
)");
QWidget* imageViewerTabWidgetContainer = new QWidget();
QGridLayout* gridLayout_imageViewerTabWidgetContainer = new QGridLayout(imageViewerTabWidgetContainer);
gridLayout_imageViewerTabWidgetContainer->setSpacing(6);
gridLayout_imageViewerTabWidgetContainer->setObjectName(QString::fromUtf8("gridLayout_imageViewerTabWidgetContainer"));
gridLayout_imageViewerTabWidgetContainer->setVerticalSpacing(6);
gridLayout_imageViewerTabWidgetContainer->setContentsMargins(0, 0, 0, 0);
gridLayout_imageViewerTabWidgetContainer->addWidget(m_imageViewerTabWidget, 0, 0, 1, 1);
imageViewerTabWidgetContainer->setStyleSheet(R"(
background: #0E1C4C;
)");
QFrame* line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Plain);
line->setStyleSheet(R"(
QWidget {
color: #2c586b;
}
)");
m_chartView = new QChartView();
m_chartView->setRenderHint(QPainter::Antialiasing);
m_chartView->setStyleSheet(R"(
background: #0D1233;
)");
//m_chartView->setBackgroundBrush(QColor("#0D1233"));
m_chart = new QChart();
m_chart->setBackgroundBrush(QColor("#0D1233"));
m_chart->legend()->hide();
//m_chart->setTitle("Simple line chart example");
QValueAxis* axisX = new QValueAxis();
QValueAxis* axisY = new QValueAxis();
setAxis(axisX, axisY);
m_chart->addAxis(axisX, Qt::AlignBottom);
m_chart->addAxis(axisY, Qt::AlignLeft);
m_chartView->setChart(m_chart);
gridLayout_hyperimgViewer->addWidget(imageViewerTabWidgetContainer, 0, 0, 1, 1);
gridLayout_hyperimgViewer->addWidget(line, 1, 0, 1, 1);
gridLayout_hyperimgViewer->addWidget(m_chartView, 2, 0, 1, 1);
gridLayout_hyperimgViewer->setRowStretch(0, 3);
gridLayout_hyperimgViewer->setRowStretch(1, 1);
gridLayout_hyperimgViewer->setRowStretch(2, 2);
dock_hyperimgViewerWidgetContents->setStyleSheet(R"(
QWidget #dock_hyperimgViewerWidgetContents{
background: #0D1233;
/*border: 1px solid #2c586b;*/
border-top: 2px solid #2c586b;
border-left: 1px solid #2c586b;
border-right: 1px solid #2c586b;
border-bottom: 2px solid #2c586b;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}
)");
dock_hyperimgViewer->setWidget(dock_hyperimgViewerWidgetContents);
mPanelMenu->addAction(dock_hyperimgViewer->toggleViewAction());
QWidget* tmp6 = new QWidget();
dock_hyperimgViewer->setTitleBarWidget(tmp6);
//轮播看板
m_dock_carousel = new CustomDockWidgetBase(QString::fromLocal8Bit("轮播"), this);
m_dock_carousel->setObjectName("mDockCarousel");
m_dock_carousel->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
mPanelMenu->addAction(m_dock_carousel->toggleViewAction());
//addDockWidget(Qt::LeftDockWidgetArea, m_dock_carousel);
QWidget* carouselContainer = new QWidget();
carouselContainer->setObjectName("carouselContainer");
carouselContainer->setStyleSheet(R"(
QWidget #carouselContainer
{
background-color: #0D1233;
border-top: 1px solid #2c586b;
border-left: 1px solid #2c586b;
border-right: 1px solid #2c586b;
border-bottom: 1px solid #2c586b;
border-top-left-radius: 0px;
border-top-right-radius: 0px;
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
}
)");
QGridLayout* gridLayout_carouselContainer = new QGridLayout(carouselContainer);
gridLayout_carouselContainer->setSpacing(0);
gridLayout_carouselContainer->setObjectName(QString::fromUtf8("gridLayout_carouselContainer"));
gridLayout_carouselContainer->setVerticalSpacing(0);
gridLayout_carouselContainer->setContentsMargins(2, 2, 2, 2);
m_carousel = new MyCarousel();
m_carousel->setObjectName(QString::fromUtf8("carousel"));
QScrollArea* sa = new QScrollArea();
sa->setObjectName("sa");
sa->setStyleSheet(R"(
border: none;
background-color: #0D1233;
)");
QGridLayout* gridLayout_sa = new QGridLayout(sa);
gridLayout_sa->setSpacing(6);
gridLayout_sa->setObjectName(QString::fromUtf8("gridLayout_sa"));
gridLayout_sa->setVerticalSpacing(0);
gridLayout_sa->setContentsMargins(0, 0, 0, 0);
m_cam_label = new QLabel();
m_cam_label->setAlignment(Qt::AlignHCenter);
m_cam_label->setStyleSheet(R"(
background-color: #0D1233;
)");
gridLayout_sa->addWidget(m_cam_label);
m_carousel->addWidget(sa);
m_carousel->setContentsMargins(0, 0, 0, 0);
QWidget* tmp8 = new QWidget();
tmp8->setStyleSheet(R"(
background-color: #0D1233;
)");
m_carousel->addWidget(tmp8);
//m_carousel->setContentsMargins(0, 0, 0, 0);
m_carousel->play();
gridLayout_carouselContainer->addWidget(m_carousel);
m_dock_carousel->setWidget(carouselContainer);
//控制看板
ui.mDockWidgetSpectrometer->setTile(QString::fromLocal8Bit("控制"));
//ui.mDockWidgetSpectrometer->show();
initControlTabwidget();
m_tabManager = new TabManager(ui.controlTabWidget, this);
//3D模型看板
ui.mDockWidgetSimulator->setTile(QString::fromLocal8Bit("3D模型"));
//ui.mDockWidgetSimulator->show();
m_view3DModelManager = new View3DModelManager(this);
QWidget* modelWidgetContainer = new QWidget();
modelWidgetContainer->setObjectName("modelWidgetContainer");
modelWidgetContainer->setStyleSheet(R"(
QWidget #modelWidgetContainer
{
background-color: #0E1C4C;
border-top: 1px solid #2c586b;
border-left: 1px solid #2c586b;
border-right: 1px solid #2c586b;
border-bottom: 1px solid #2c586b;
border-top-left-radius: 0px;
border-top-right-radius: 0px;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}
)");
QGridLayout* gridLayout_modelWidgetContainer = new QGridLayout(modelWidgetContainer);
gridLayout_modelWidgetContainer->setSpacing(0);
gridLayout_modelWidgetContainer->setObjectName(QString::fromUtf8("gridLayout_modelWidgetContainer"));
gridLayout_modelWidgetContainer->setVerticalSpacing(0);
gridLayout_modelWidgetContainer->setContentsMargins(2, 2, 2, 2);
gridLayout_modelWidgetContainer->addWidget(m_view3DModelManager);
connect(m_view3DModelManager, SIGNAL(created3DModelPlantPhenotype()), this, SLOT(onCreated3DModelPlantPhenotype()));
connect(m_view3DModelManager, SIGNAL(created3DModelOneMotor()), this, SLOT(onCreated3DModelOneMotor()));
ui.mDockWidgetSimulator->setWidget(modelWidgetContainer);
//看板排版
splitDockWidget(dock_layers, dock_hyperimgViewer, Qt::Horizontal);
splitDockWidget(dock_hyperimgViewer, m_dock_carousel, Qt::Horizontal);
//m_dock_carousel->show();
//ui.mDockWidgetRGBCamera->setMinimumWidth(449);
//ui.mDockWidgetRGBCamera->setMaximumWidth(450);
//ui.mDockWidgetRGBCamera->setMinimumHeight(497);
//ui.mDockWidgetRGBCamera->setMaximumHeight(498);
splitDockWidget(dock_layers, ui.mDockWidgetSimulator, Qt::Vertical);
splitDockWidget(m_dock_carousel, ui.mDockWidgetSpectrometer, Qt::Vertical);
setStyleSheet(R"(
QMainWindow::separator{
width: 16px;
height: 16px;
background: #040125; /* 可以添加背景色 */
/*border: 1px solid #808080;*/ /* 可以添加边框 */
}
QDockWidget {
border: 2px solid #2a347a; /* 深蓝色边框 */
background-color: red; /* 主体背景色 */
color: white; /* 标题文字颜色 */
border-radius: 4px;
}
/* 标题栏 */
QDockWidget::title {
background-color: #0E1C4C; /* 标题栏背景色 */
text-align: left; /* 标题文字居中 */
/*padding: 4px;*/
}
/* 可选:控制 DockWidget 的关闭按钮样式 */
QDockWidget::close-button, QDockWidget::float-button {
background: transparent;
border: none;
}
QDockWidget::close-button:hover, QDockWidget::float-button:hover {
background: rgba(255,255,255,0.2);
}
)");
createActionGroups();
connect(mImagerGroup, &QActionGroup::triggered, this, &HPPA::selectingImager);
createMoveplatformActionGroup();
connect(moveplatformActionGroup, &QActionGroup::triggered, this, &HPPA::selectingMoveplatform);
createScenarioActionGroup();
connect(m_ScenarioActionGroup, &QActionGroup::triggered, this, &HPPA::selectScenario);
ui.mDockWidgetSimulator->setFeatures(QDockWidget::DockWidgetClosable);
QString strPath = QCoreApplication::applicationDirPath() + "/UILayout.ini";
QFile file(strPath);
if (file.open(QIODevice::ReadOnly))
{
QByteArray ba;
QDataStream in(&file);
in >> ba;
file.close();
this->restoreState(ba);
}
this->showMaximized();
}
void HPPA::initMenubarToolbar()
{
//自定义菜单栏和工具栏
QWidget* menuWidget = new WidgetWithBackgroundPicture();
//menuWidget->setFixedWidth(200);
menuWidget->setFixedHeight(66);
QHBoxLayout* hLayout_menuWidget = new QHBoxLayout(menuWidget);
//auto menuBar_tmp = menuBar();
auto menuBar_tmp = ui.menuBar;
hLayout_menuWidget->addWidget(menuBar_tmp);
menuBar_tmp->setAutoFillBackground(false);
menuBar_tmp->setStyleSheet(R"(
QMenuBar {
background: transparent;/*transparent*/
border: none;
}
QMenuBar::item {
background: transparent;
color: white; /* 根据你的背景调整文字颜色 */
padding: 4px 8px;
padding-top: 8px;
padding-bottom: 8px;
}
QMenuBar::item:selected {
background: rgba(255, 255, 255, 50); /* 轻微高亮 */
}
QMenu {
background-color: #0A1245; /* 菜单背景色 */
border: 1px solid gray; /* 可选,边框样式 */
color: white; /* 根据你的背景调整文字颜色 */
}
QMenu::item:selected {
background-color: rgba(255, 255, 255, 50); /* 选中时的背景色 */
color: white; /* 选中项字体颜色,可选 */
}
)");
hLayout_menuWidget->addStretch();
QPushButton* closeBtn = new QPushButton(QString::fromLocal8Bit("退出平台"));
closeBtn->setStyleSheet(R"(
QPushButton {
background: #002CE0;
color: white;
font-size: 14px;
border: none;
padding: 8px;
}
QPushButton:hover {
background: #34495e;
}
)");
hLayout_menuWidget->addWidget(closeBtn);
QWidget* toolBarWidget = new QWidget();
toolBarWidget->setStyleSheet("background-color: #0D1233;");
QHBoxLayout* hLayout_toolBarWidget = new QHBoxLayout(toolBarWidget);
//QToolBar* toolBar = this->findChild<QToolBar*>("mainToolBar");
QToolBar* toolBar = ui.mainToolBar;
//hLayout_toolBarWidget->addWidget(toolBar);
toolBar->setAttribute(Qt::WA_TranslucentBackground, true);
toolBar->setAutoFillBackground(false);
toolBar->setIconSize(QSize(56, 56));
toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
//在工具栏上添加输入框QLineEdit
frame_number = new QLineEdit(ui.mainToolBar);
frame_number->setStyleSheet("QLineEdit{background-color:rgb(255,255,255);}");
frame_number->setMaximumWidth(100);
frame_number->setText("5000");
QAction* action = ui.mainToolBar->insertWidget(ui.action_start_recording, frame_number);
m_FilenameLineEdit = new QLineEdit(ui.mainToolBar);
m_FilenameLineEdit->setStyleSheet("QLineEdit{background-color:rgb(255,255,255);}");
m_FilenameLineEdit->setMaximumWidth(100);
m_FilenameLineEdit->setText("tmp_image");
QAction* action1 = ui.mainToolBar->insertWidget(ui.action_start_recording, m_FilenameLineEdit);
ui.action_connect_imager->setIcon(QIcon(".//icon//all//connect_imager.png"));
ui.action_auto_exposure->setIcon(QIcon(".//icon//all//exposure.png"));
ui.action_focus->setIcon(QIcon(".//icon//all//focus.png"));
ui.action_dark->setIcon(QIcon(".//icon//all//dark.png"));
ui.action_reference->setIcon(QIcon(".//icon//all//reference.png"));
// 使用样式表设置透明背景
toolBar->setStyleSheet(R"(
QToolBar {
background: #0D1233;/*transparent*/
border: 1px solid #444;
border-radius: 6px;
}
QToolButton {
background: transparent;
color: white; /* 可根据背景调整文字颜色 */
padding: 4px;
margin: 0 0 0 6px;
}
QToolButton:hover {
background: rgba(255,255,255,50); /* 悬停时轻微高亮 */
}
)");
QWidget* topWidget = new QWidget();
topWidget->setStyleSheet("background-color: #040125;");
QVBoxLayout* verticalLayout_topWidget = new QVBoxLayout(topWidget);
verticalLayout_topWidget->addWidget(menuWidget);
//verticalLayout_topWidget->addWidget(toolBarWidget);
setMenuWidget(topWidget);
}
void HPPA::initControlTabwidget()
{
//rgb相机
m_RgbCameraThread = new QThread();
m_RgbCamera = new RgbCameraOperation();
m_RgbCamera->moveToThread(m_RgbCameraThread);
m_RgbCameraThread->start();
connect(ui.open_rgb_camera_btn, SIGNAL(clicked()), m_RgbCamera, SLOT(OpenCamera()));//使用信号通知主线程ui线程刷新视频 → 成功,但是界面卡顿
connect(m_RgbCamera, SIGNAL(PlotSignal()), this, SLOT(onPlotRgbImage()));
//m_RgbCamera->setCallback(onPlotRgbImage);
//connect(this->ui.open_rgb_camera_btn, SIGNAL(clicked()), m_RgbCamera, SLOT(OpenCamera_callback()));//使用回调函数来刷新主线程ui线程上的视频 → 失败
connect(ui.close_rgb_camera_btn, SIGNAL(clicked()), this, SLOT(onCloseRgbCamera()));//关闭相机
connect(m_RgbCamera, SIGNAL(CamClosed()), this, SLOT(onClearLabel()));
//图像控制
m_ic = new ImageControl();
m_ic->setWindowFlags(Qt::Widget);
connect(m_ic, SIGNAL(bandSelectionChanged(double, double, double)),
this, SLOT(onBandSelectionChanged(double, double, double)));
ui.controlTabWidget->addTab(m_ic, QString::fromLocal8Bit("图像控制"));
//升降桌dock
m_adt = new adjustTable();
m_adt->setWindowFlags(Qt::Widget);
ui.controlTabWidget->addTab(m_adt, QString::fromLocal8Bit("升降桌"));
//电源控制
m_pc = new PowerControl();
m_pc->setWindowFlags(Qt::Widget);
ui.controlTabWidget->addTab(m_pc, QString::fromLocal8Bit("电源控制"));
//机械臂控制
m_rac = new RobotArmControl();
connect(m_rac->robotController, SIGNAL(hsiRecordSignal(int)), this, SLOT(recordFromRobotArm(int)));
m_rac->setWindowFlags(Qt::Widget);
ui.controlTabWidget->addTab(m_rac, QString::fromLocal8Bit("机械臂控制"));
//1轴马达控制
m_omc = new OneMotorControl();
m_omc->setWindowFlags(Qt::Widget);
ui.controlTabWidget->addTab(m_omc, QString::fromLocal8Bit("1轴马达控制"));
//2轴马达控制
m_tmc = new TwoMotorControl(this);
//connect(m_tmc, SIGNAL(startLineNumSignal(int)), this, SLOT(onCreateTab(int)));
connect(m_tmc, SIGNAL(sequenceComplete()), this, SLOT(onsequenceComplete()));
m_tmc->setWindowFlags(Qt::Widget);
ui.controlTabWidget->addTab(m_tmc, QString::fromLocal8Bit("2轴控制"));
// Connect ImageControl band change to re-render (m_ic created in initControlTabwidget)
connect(m_ic, SIGNAL(bandSelectionChanged(double,double,double)),
this, SLOT(onBandSelectionChanged(double,double,double)));
}
void HPPA::recordFromRobotArm(int fileCounter)
{
//qDebug() << "recordFromRobotArm" << fileCounter;
if (fileCounter == -1)
{
m_Imager->setRecordControlState(false);
ui.action_start_recording->setText(QString::fromLocal8Bit("采集"));
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
//qDebug() << "recordFromRobotArm: 1111111111111111111111";
return;
}
if (fileCounter - 1 == 0)
{
//m_imageViewerTabWidget->clear();
removeAllLayersInRasterGroup();
}
onCreateTab("img");
emit StartRecordSignal();
ui.action_start_recording->setText(QString::fromLocal8Bit("采集中"));
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(255,0,0);}");
//qDebug() << "recordFromRobotArm: 2222222222222222222222";
}
void HPPA::createActionGroups()
{
// Imager Tool Group
mImagerGroup = new QActionGroup(this);
mImagerGroup->addAction(ui.mActionPica_L);
mImagerGroup->addAction(ui.mActionPika_XC2);
mImagerGroup->addAction(ui.mActionCorning_410);
mImagerGroup->addAction(ui.mActionPica_NIR);
// 读取上次选择的结果
QSettings settings;
QString lastSelectedAction = settings.value("LastSelectedImagerAction").toString();
// 恢复上次选择的结果
if (lastSelectedAction == "mActionPica_L")
{
ui.mActionPica_L->setChecked(true);
}
else if (lastSelectedAction == "mActionPica_NIR")
{
ui.mActionPica_NIR->setChecked(true);
}
else if (lastSelectedAction == "mActionPika_XC2")
{
ui.mActionPika_XC2->setChecked(true);
}
else if (lastSelectedAction == "mActionCorning_410")
{
ui.mActionCorning_410->setChecked(true);
}
}
void HPPA::selectingImager(QAction* selectedAction)
{
QSettings settings;
settings.setValue("LastSelectedImagerAction", selectedAction->objectName());
settings.sync();
}
void HPPA::createMoveplatformActionGroup()
{
moveplatformActionGroup = new QActionGroup(this);
moveplatformActionGroup->addAction(ui.mAction_is_no_motor);
moveplatformActionGroup->addAction(ui.mAction_RobotArm);
moveplatformActionGroup->addAction(ui.mAction_1AxisMotor);
moveplatformActionGroup->addAction(ui.mAction_2AxisMotor_new);
// 读取上次选择的结果
QSettings settings;
QString lastSelectedAction = settings.value("LastSelectedMoveplatform").toString();
// 恢复上次选择的结果
if (lastSelectedAction == "mAction_is_no_motor")
{
ui.mAction_is_no_motor->setChecked(true);
}
else if (lastSelectedAction == "mAction_RobotArm")
{
ui.mAction_RobotArm->setChecked(true);
}
else if (lastSelectedAction == "mAction_1AxisMotor")
{
ui.mAction_1AxisMotor->setChecked(true);
}
else if (lastSelectedAction == "mAction_2AxisMotor_new")
{
ui.mAction_2AxisMotor_new->setChecked(true);
}
}
void HPPA::selectingMoveplatform(QAction* selectedAction)
{
QSettings settings;
settings.setValue("LastSelectedMoveplatform", selectedAction->objectName());
settings.sync();
}
HPPA::~HPPA()
{
QString strPath = QCoreApplication::applicationDirPath() + "/UILayout.ini";
QFile file(strPath);
if (file.open(QIODevice::WriteOnly)) {
QDataStream outfile(&file);
QByteArray ba = this->saveState();
outfile << ba;
file.close();
}
if (m_Imager != nullptr)
{
//m_Imager->~ResononNirImager();//释放资源
delete m_Imager;
}
if (s_instance == this)
{
s_instance = nullptr;
}
}
void HPPA::removeLayerByTreeIndex()
{
QModelIndex currentIndexTmp = m_layerTreeView->currentIndex();
if (!currentIndexTmp.isValid()) return;
LayerTreeModel* model = const_cast<LayerTreeModel*>(static_cast<const LayerTreeModel*>(currentIndexTmp.model()));
if (!model) return;
LayerTreeNode* node = static_cast<LayerTreeNode*>(currentIndexTmp.internalPointer());
if (!node || node->type() != LayerTreeNode::Type::Layer) return;
auto* layerNode = static_cast<LayerTreeLayerNode*>(node);
MapLayer* mapLayer = layerNode->mapLayer();
QWidget* layerWidget = nullptr;
if (mapLayer && m_MapLayerStore)
{
layerWidget = m_MapLayerStore->widgetForLayer(mapLayer);
m_MapLayerStore->removeLayer(mapLayer);
}
if (layerWidget && m_imageViewerTabWidget)
{
const int tabIndex = m_imageViewerTabWidget->indexOf(layerWidget);
if (tabIndex >= 0)
{
m_imageViewerTabWidget->removeTab(tabIndex);
}
layerWidget->deleteLater();
}
LayerTreeNode* parent = node->parentNode();
int row = node->rowInParent();
LayerTreeNode* removed = model->removeNode(parent, row);
if (removed)
{
delete removed;
}
}
void HPPA::removeAllLayersInRasterGroup()
{
if (!m_LayerTreeModel || !m_RasterGroup) return;
QVector<LayerTreeNode*> pending;
for (int i = 0; i < m_RasterGroup->childCount(); ++i)
{
pending.push_back(m_RasterGroup->childAt(i));
}
while (!pending.isEmpty())
{
LayerTreeNode* node = pending.back();
pending.pop_back();
if (!node) continue;
for (int i = 0; i < node->childCount(); ++i)
{
pending.push_back(node->childAt(i));
}
if (node->type() != LayerTreeNode::Type::Layer) continue;
auto* layerNode = static_cast<LayerTreeLayerNode*>(node);
MapLayer* mapLayer = layerNode->mapLayer();
QWidget* layerWidget = nullptr;
if (mapLayer && m_MapLayerStore)
{
layerWidget = m_MapLayerStore->widgetForLayer(mapLayer);
m_MapLayerStore->removeLayer(mapLayer);
}
if (layerWidget && m_imageViewerTabWidget)
{
const int tabIndex = m_imageViewerTabWidget->indexOf(layerWidget);
if (tabIndex >= 0)
{
m_imageViewerTabWidget->removeTab(tabIndex);
}
layerWidget->deleteLater();
}
}
while (m_RasterGroup->childCount() > 0)
{
const int row = m_RasterGroup->childCount() - 1;
LayerTreeNode* removed = m_LayerTreeModel->removeNode(m_RasterGroup, row);
if (removed)
{
delete removed;
}
}
}
void HPPA::initPanelToolbar()
{
mPanelMenu = new QMenu(QString::fromLocal8Bit("面板"), this);//create panel menu
mPanelMenu->setObjectName(QStringLiteral("mPanelMenu"));
mToolbarMenu = new QMenu(QString::fromLocal8Bit("工具栏"), this);//create toolbar menu
mToolbarMenu->setObjectName(QStringLiteral("mToolbarMenu"));
ui.mWindowsMenu->addSeparator();
ui.mWindowsMenu->addMenu(mPanelMenu);
ui.mWindowsMenu->addMenu(mToolbarMenu);
mPanelMenu->addAction(ui.mDockWidgetSpectrometer->toggleViewAction());
mPanelMenu->addAction(ui.mDockWidgetSimulator->toggleViewAction());
mToolbarMenu->addAction(ui.mainToolBar->toggleViewAction());
}
void HPPA::initMapTools()
{
ui.mActionPan->setCheckable(true);
ui.mActionSpectral->setCheckable(true);
m_mapTools = new MapTools(this);
m_mapTools->mapToolPan()->setAction(ui.mActionPan);
m_mapTools->mapToolSpectral()->setAction(ui.mActionSpectral);
connect(m_mapTools->mapToolSpectral(), SIGNAL(spectralClicked(int,int,QVector<double>,QVector<double>)),
this, SLOT(onLeftMouseButtonPressed(int,int,QVector<double>,QVector<double>)));
connect(ui.mActionPan, SIGNAL(triggered()), this, SLOT(onMapToolPanTriggered()));
connect(ui.mActionSpectral, SIGNAL(triggered()), this, SLOT(onMapToolSpectralTriggered()));
// Default tool: pan
//ui.mActionPan->trigger();
}
void HPPA::onMapToolPanTriggered()
{
// Find the current Mapcavas
QWidget* currentWidget = m_imageViewerTabWidget->currentWidget();
if (!currentWidget)
{
ui.mActionPan->setChecked(false);
return;
}
QList<Mapcavas*> canvases = currentWidget->findChildren<Mapcavas*>();
if (canvases.isEmpty()) return;
Mapcavas* canvas = canvases[0];
// Set canvas on shared tool and activate
m_mapTools->setMapcavas(canvas);
// Uncheck the other action
ui.mActionSpectral->setChecked(false);
canvas->setMapTool(m_mapTools->mapToolPan());
}
void HPPA::onMapToolSpectralTriggered()
{
// Find the current Mapcavas
QWidget* currentWidget = m_imageViewerTabWidget->currentWidget();
if (!currentWidget) return;
QList<Mapcavas*> canvases = currentWidget->findChildren<Mapcavas*>();
if (canvases.isEmpty()) return;
Mapcavas* canvas = canvases[0];
// Set canvas on shared tool and activate
m_mapTools->setMapcavas(canvas);
// Uncheck the other action
ui.mActionPan->setChecked(false);
canvas->setMapTool(m_mapTools->mapToolSpectral());
}
//----------------------------------------------------
void HPPA::createScenarioActionGroup()
{
m_ScenarioActionGroup = new QActionGroup(this);
m_ScenarioActionGroup->addAction(ui.mActionOneMotorScenario);
m_ScenarioActionGroup->addAction(ui.mActionPlantPhenotypeScenario);
// 读取上次选择的结果
QSettings settings;
QString lastSelectedAction = settings.value("LastSelectedScenario").toString();
// 恢复上次选择的结果
if (lastSelectedAction == "mActionOneMotorScenario")
{
ui.mActionOneMotorScenario->setChecked(true);
ui.mActionOneMotorScenario->trigger();
}
else if (lastSelectedAction == "mActionPlantPhenotypeScenario")
{
ui.mActionPlantPhenotypeScenario->setChecked(true);
ui.mActionPlantPhenotypeScenario->trigger();
}
}
void HPPA::selectScenario(QAction* selectedAction)
{
QSettings settings;
settings.setValue("LastSelectedScenario", selectedAction->objectName());
settings.sync();
}
void HPPA::onCreated3DModelOneMotor()
{
connect(m_omc, SIGNAL(broadcastLocationSignal(std::vector<double>)), m_view3DModelManager->m_viewMotor, SLOT(setLoc(std::vector<double>)));
}
void HPPA::createOneMotorScenario()
{
//if (ui.mActionOneMotorScenario->isChecked())
// return;
//清除所有DockWidget
//QList<QDockWidget*> dockWidgets = this->findChildren<QDockWidget*>();
//for (QDockWidget* dock : dockWidgets)
//{
// dock->hide();
//}
//在菜单中选择移动平台
ui.mAction_1AxisMotor->setChecked(true);
//右下角控制tab
m_tabManager->hideTab(ui.rgbCameraWidget);
m_tabManager->hideTab(m_adt);
m_tabManager->hideTab(m_pc);
m_tabManager->hideTab(m_rac);
m_tabManager->hideTab(m_tmc);
m_tabManager->showTab(m_omc);
m_view3DModelManager->switchScenario(View3DModelManager::ScenarioType::OneMotor);
//右上角轮播
}
void HPPA::onCreated3DModelPlantPhenotype()
{
connect(m_tmc, SIGNAL(broadcastLocationSignal(std::vector<double>)), m_view3DModelManager->m_viewPlant, SLOT(setLoc(std::vector<double>)));
}
void HPPA::createPlantPhenotypeScenario()
{
//if (ui.mActionPlantPhenotypeScenario->isChecked())
// return;
//在菜单中选择移动平台
ui.mAction_2AxisMotor_new->setChecked(true);
//右下角控制tab
m_tabManager->hideTab(m_rac);
m_tabManager->hideTab(m_omc);
m_tabManager->showTab(ui.rgbCameraWidget);
m_tabManager->showTab(m_adt);
m_tabManager->showTab(m_pc);
m_tabManager->showTab(m_tmc);
m_view3DModelManager->switchScenario(View3DModelManager::ScenarioType::PlantPhenotype);
//右上角轮播
}
void HPPA::CalculateIntegratioinTimeRange()
{
double range = 1 / m_Imager->getFramerate() * 1000;//毫秒
ui.IntegratioinTimeSlider->blockSignals(true);//因为setMaximum会触发valueChanged信号所以调用setMaximum前需要阻断信号
ui.IntegratioinTimeSlider->setMaximum(range);
ui.IntegratioinTimeSlider->blockSignals(false);
}
void HPPA::onStartRecordStep1()
{
QAction* checked = moveplatformActionGroup->checkedAction();
if (!checked)
{
QMessageBox msgBox;
msgBox.setText(QString::fromLocal8Bit("请选择扫描平台!"));
msgBox.exec();
return;
}
//判断是否覆盖存在的文件
FileOperation* fileOperation = new FileOperation();
string directory = fileOperation->getDirectoryFromString();
//string imgPath = directory + "\\tmp_image";
string imgPath = directory + "\\" + m_FilenameLineEdit->text().toStdString();
string x_location = removeFileExtension(imgPath) + "_x_location.pos";
m_RecordState += 1;
if (m_RecordState % 2 == 1)
{
m_RecordState -= 1;
string tmp = imgPath + "_" + std::to_string(0) + ".bil";
int x = _access(tmp.c_str(), 0);
if (!x)//如果文件存在就执行此if的代码
{
enum QMessageBox::StandardButton response = QMessageBox::question(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("文件存在!是否覆盖?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);;
if (response == QMessageBox::Yes)//
{
//std::cout << "覆盖" << std::endl;
}
else
{
//std::cout << "不覆盖" << std::endl;
return;
}
}
}
else
{
m_RecordState -= 1;
}
QString checkedName = checked->objectName();
if (checkedName == "mAction_is_no_motor")
{
m_RecordState += 1;
if (m_RecordState % 2 == 1)
{
//m_imageViewerTabWidget->clear();
removeAllLayersInRasterGroup();
m_Imager->setFileName2Save(imgPath);
m_Imager->setFrameNumber(this->frame_number->text().toInt());
emit StartRecordSignal();//发射开始采集信号
ui.action_start_recording->setText(QString::fromLocal8Bit("停止采集"));
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(255,0,0);}");
}
else
{
m_Imager->setRecordControlState(false);//光谱仪停止采集
m_RecordState -= 1;
ui.action_start_recording->setText(QString::fromLocal8Bit("采集"));
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
}
return;
}
else if (checkedName == "mAction_1AxisMotor")
{
m_RecordState += 1;
if (m_RecordState % 2 == 1)
{
//m_imageViewerTabWidget->clear();
removeAllLayersInRasterGroup();
ui.action_start_recording->setText(QString::fromLocal8Bit("停止采集"));
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(255,0,0);}");
//应该先控制马达运动,当马达运动后,再开始光谱仪采集(发射开始采集信号)
m_Imager->setFileName2Save(imgPath);
m_Imager->setFrameNumber(this->frame_number->text().toInt());
m_omc->setImager(m_Imager);
m_omc->run();
}
else
{
m_omc->stop();
m_RecordState -= 1;
ui.action_start_recording->setText(QString::fromLocal8Bit("采集"));
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
}
return;
}
else if (checkedName == "mAction_2AxisMotor_new")
{
m_RecordState += 1;
if (m_RecordState % 2 == 1)
{
//m_imageViewerTabWidget->clear();
removeAllLayersInRasterGroup();
m_Imager->setFileName2Save(imgPath);
m_Imager->setFrameNumber(this->frame_number->text().toInt());
m_tmc->setImager(m_Imager);
m_tmc->setPosFileName(QString::fromStdString(x_location));
m_tmc->run();
ui.action_start_recording->setText(QString::fromLocal8Bit("停止采集"));
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(255,0,0);}");
}
else
{
m_tmc->stop();
m_RecordState--;
ui.action_start_recording->setText(QString::fromLocal8Bit("采集"));
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
}
return;
}
else if (checkedName == "mAction_RobotArm")
{
//先判断是否选择了任务执行函数RobotArmControl::executeTask修复界面显示bug
m_Imager->setFileName2Save(imgPath);
m_Imager->setFrameNumber(this->frame_number->text().toInt());
m_rac->executeTaskWithHyperImager();
return;
}
}
QWidget* HPPA::onCreateTab(QString tabName)
{
QWidget* tabTmp = new QWidget();
QGridLayout* GridLayout = new QGridLayout();
GridLayout->addWidget(new Mapcavas(tabTmp));
tabTmp->setLayout(GridLayout);
m_imageViewerTabWidget->addTab(tabTmp, tabName);
m_imageViewerTabWidget->setCurrentIndex(m_imageViewerTabWidget->count() - 1);
return tabTmp;
}
void HPPA::onTabWidgetCurrentChanged(int index)//代码新建一个tab会调用onTabWidgetCurrentChanged函数
{
if (index < 0)//当删除所有tab时index=-1
{
return;
}
//记录当前
m_TabWidgetCurrentIndex = index;
//获取绘图控件
QWidget* currentWidget = m_imageViewerTabWidget->widget(index);
QList<Mapcavas*> currentImageViewer = currentWidget->findChildren<Mapcavas*>();
//先disconnect然后再connect否则每次切换一次都会connect一次会累积connect很多次
disconnect(currentImageViewer[0], SIGNAL(leftMouseButtonPressed(int,int,QVector<double>,QVector<double>)), this, SLOT(onLeftMouseButtonPressed(int,int,QVector<double>,QVector<double>)));
connect(currentImageViewer[0], SIGNAL(leftMouseButtonPressed(int,int,QVector<double>,QVector<double>)), this, SLOT(onLeftMouseButtonPressed(int,int,QVector<double>,QVector<double>)));
// Re-apply the current map tool to the new canvas
Mapcavas* canvas = currentImageViewer[0];
m_mapTools->setMapcavas(canvas);
if (ui.mActionPan->isChecked())
{
canvas->setMapTool(m_mapTools->mapToolPan());
}
else if (ui.mActionSpectral->isChecked())
{
canvas->setMapTool(m_mapTools->mapToolSpectral());
}
}
void HPPA::onActionOpenDirectory()
{
FileOperation* fileOperation = new FileOperation();
string directory = fileOperation->getDirectoryFromString();
QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(directory)));
}
void HPPA::OnFramerateLineeditEditingFinished()
{
std::cout << "Lineedit设置帧率------------------------------------------" << std::endl;
m_Imager->setFramerate(this->ui.framerate_lineEdit->text().toDouble());
ui.FramerateSlider->setValue(ui.framerate_lineEdit->text().toDouble());
CalculateIntegratioinTimeRange();
}
void HPPA::OnFramerateSliderChanged(double framerate)
{
std::cout << "Slider设置帧率------------------------------------------" << std::endl;
m_Imager->setFramerate(this->ui.framerate_lineEdit->text().toDouble());
ui.framerate_lineEdit->setText(QString::number(framerate));
CalculateIntegratioinTimeRange();
}
void HPPA::OnIntegratioinTimeEditingFinished()
{
std::cout << "Lineedit设置积分时间------------------------------------------" << std::endl;
m_Imager->setIntegrationTime(this->ui.integratioin_time_lineEdit->text().toDouble());
ui.IntegratioinTimeSlider->setValue(ui.integratioin_time_lineEdit->text().toDouble());
}
void HPPA::OnIntegratioinTimeSliderChanged(double IntegratioinTime)
{
std::cout << "Slider设置积分时间------------------------------------------" << std::endl;
m_Imager->setIntegrationTime(IntegratioinTime);
ui.integratioin_time_lineEdit->setText(QString::number(IntegratioinTime));
}
void HPPA::OnGainEditingFinished()
{
m_Imager->setGain(this->ui.gain_lineEdit->text().toDouble());
ui.GainSlider->setValue(ui.gain_lineEdit->text().toDouble());
}
void HPPA::OnGainSliderChanged(double Gain)
{
m_Imager->setGain(this->ui.gain_lineEdit->text().toDouble());
ui.gain_lineEdit->setText(QString::number(Gain));
}
void HPPA::onLeftMouseButtonPressed(int x, int y, QVector<double> wavelengths, QVector<double> spectrum)
{
Q_UNUSED(x);
Q_UNUSED(y);
try
{
//正在采集时,不能显示光谱曲线
if (m_RecordState % 2 == 1)
{
return;
}
if (spectrum.isEmpty())
{
return;
}
QLineSeries* series = new QLineSeries();
const int count = qMin(wavelengths.size(), spectrum.size());
if (count > 0)
{
for (int i = 0; i < count; ++i)
{
series->append(wavelengths[i], spectrum[i]);
}
}
else
{
for (int i = 0; i < spectrum.size(); ++i)
{
series->append(i, spectrum[i]);
}
}
series->setPen(QPen(QColor("#FF928A"), 2));
m_chart->removeAllSeries();
m_chart->addSeries(series);
m_chart->createDefaultAxes();
QValueAxis* axisX = qobject_cast<QValueAxis*>(m_chart->axisX());
QValueAxis* axisY = qobject_cast<QValueAxis*>(m_chart->axisY());
setAxis(axisX, axisY);
}
catch (const std::exception&)
{
std::cout << "显示光谱有错误!" << std::endl;
}
}
void HPPA::setAxis(QValueAxis* axisX, QValueAxis* axisY)
{
if (axisX && axisY)
{
QPen axisPen(QColor("#ACCDFF"));
axisPen.setWidth(1);
// 坐标轴线颜色
axisX->setLinePen(axisPen);
axisY->setLinePen(axisPen);
// 坐标标签颜色
axisX->setLabelsColor(QColor("#ACCDFF"));
axisY->setLabelsColor(QColor("#ACCDFF"));
// 网格线颜色
QPen gridPen(QColor("#262A4C"));
gridPen.setStyle(Qt::DashLine);
gridPen.setWidth(2);
axisX->setGridLinePen(gridPen);
axisY->setGridLinePen(gridPen);
}
}
void HPPA::timerEvent(QTimerEvent* event)
{
}
void HPPA::setImagerSimulationPos(double x, double y)
{
x = widthScale * x;
y = heightScale * y;
//ui.graphicsView->imager->setPos(x, y);
}
void HPPA::onimagerSimulatorMove(int x, int y)
{
}
void HPPA::OnSendLogToCallClass(QString str)
{
qDebug() << str;
}
void HPPA::onPlotRgbImage()
{
//std::cout << "显示视频+++++++++++++++++++++++++++++++++++++++++++" << std::endl;
QPixmap pixmap = QPixmap::fromImage(m_RgbCamera->m_qImage);
int width = m_cam_label->width();
int height = m_cam_label->height();
QPixmap fitpixmap = pixmap.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation); //按比例缩放
m_cam_label->setPixmap(fitpixmap);
}
void HPPA::onCloseRgbCamera()
{
//std::cout << "关闭视频+++++++++++++++++++++++++++++++++++++++++++" << std::endl;
m_RgbCamera->CloseCamera();
}
void HPPA::onClearLabel()
{
m_cam_label->clear();
m_cam_label->setText("closed");
}
void HPPA::onCopyFinished()
{
this->setEnabled(true);
}
void HPPA::getRequest(QString str)
{
QNetworkRequest request;
QNetworkAccessManager* naManager = new QNetworkAccessManager(this);
QMetaObject::Connection connRet = QObject::connect(naManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));
Q_ASSERT(connRet);
request.setUrl(QUrl(str));
QNetworkReply* reply = naManager->get(request);
}
void HPPA::requestFinished(QNetworkReply* reply) {
// 获取http状态码
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (statusCode.isValid())
qDebug() << "status code=" << statusCode.toInt();
QVariant reason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
if (reason.isValid())
qDebug() << "reason=" << reason.toString();
QNetworkReply::NetworkError err = reply->error();
if (err != QNetworkReply::NoError) {
qDebug() << "Failed: " << reply->errorString();
}
else {
// 获取返回内容
qDebug() << reply->readAll();
}
}
void HPPA::onExit()
{
this->close();
}
void HPPA::onOpenImg()
{
// 1) 弹出文件对话框获取uri
QString uri = QFileDialog::getOpenFileName(this, tr("Open Image"), QString(), tr("Raster Files (*.bil *.bip *.tif *.tiff *.img *.bsq);;All Files (*)"));
if (uri.isEmpty())
return;
// 2) 创建 RasterLayer然后添加到图层管理器
if (!m_LayerTreeModel || !m_RasterGroup)
{
QMessageBox::warning(this, tr("Error"), tr("Layer model is not initialized."));
return;
}
QFileInfo fi(uri);
QString baseName = fi.completeBaseName();
RasterLayer* rl = new RasterLayer(baseName, uri);
auto* layerNode = new LayerTreeLayerNode(rl);
m_LayerTreeModel->addLayer(m_RasterGroup, layerNode);
QWidget* mapcavasContainer = onCreateTab(baseName);
if (m_MapLayerStore) m_MapLayerStore->addLayer(rl, mapcavasContainer);
QList<Mapcavas*> mapcavas = mapcavasContainer->findChildren<Mapcavas*>();
mapcavas[0]->setLayers(rl);
mapcavas[0]->freshmap();
}
void HPPA::onconnect()
{
if (m_Imager != nullptr)
{
//std::cout << "相机已经连接!" << std::endl;
return;
}
try
{
//采集影像线程放入新线程中采集以免在采集过程中界面卡死https://www.cnblogs.com/xia-weiwen/p/10306089.html
m_RecordThread = new QThread();
//根据选择的相机类型创建对象mImagerGroup
QString imagerSelected = mImagerGroup->checkedAction()->objectName();
if (imagerSelected == "mActionPica_L")
{
m_Imager = new ResononPicaLImager();
}
else if (imagerSelected == "mActionPica_NIR")
{
m_Imager = new ResononNirImager();
}
else if (imagerSelected == "mActionPika_XC2")
{
m_Imager = new ResononPicaLImager();
}
else if (imagerSelected == "mActionCorning_410")
{
m_Imager = new Corning410Imager();
}
else
{
QMessageBox msgBox;
msgBox.setText(QString::fromLocal8Bit("请选择相机!"));
msgBox.exec();
return;
}
m_Imager->moveToThread(m_RecordThread);
m_RecordThread->start();
m_Imager->connect_imager(frame_number->text().toInt());
m_Imager->setFileName2Save(m_FilenameLineEdit->text().toStdString());
connect(m_Imager, SIGNAL(PlotSignal(int, int, QString)), this, SLOT(onPlotHyperspectralImageRgbImage(int, int, QString)));
connect(m_Imager, SIGNAL(RecordFinishedSignal_WhenFrameNumberMeet()), this, SLOT(onRecordFinishedSignal_WhenFrameNumberMeet()));
connect(m_Imager, SIGNAL(RecordFinishedSignal_WhenFrameNumberNotMeet()), this, SLOT(onRecordFinishedSignal_WhenFrameNumberNotMeet()));
connect(m_Imager, SIGNAL(SpectralSignal(int)), this, SLOT(PlotSpectral(int)));
//connect(m_Imager, SIGNAL(testImagerStatus()), this, SLOT(testImagerStatus()));
//文件拷贝
m_CopyFileThread = new QThread();
m_FileOperation = new FileOperation();
m_FileOperation->moveToThread(m_CopyFileThread);
m_CopyFileThread->start();
connect(this, SIGNAL(CopyFileThreadSignal(QString, QString)), m_FileOperation, SLOT(copyFile(QString, QString)));
connect(m_FileOperation, SIGNAL(CopyFinishedSignal()), this, SLOT(onCopyFinished()));
//检测光谱仪连接状态
m_TestImagerStausThread = new WorkerThread(m_Imager);
connect(this->ui.action_auto_exposure, SIGNAL(triggered()), this, SLOT(onAutoExposure()));
connect(this->ui.action_focus, SIGNAL(triggered()), this, SLOT(onFocus1()));
connect(this, SIGNAL(StartFocusSignal()), m_Imager, SLOT(focus()));
connect(this->ui.action_dark, SIGNAL(triggered()), this, SLOT(onDark()));
connect(this->ui.action_reference, SIGNAL(triggered()), this, SLOT(onReference()));
connect(this->ui.action_start_recording, SIGNAL(triggered()), this, SLOT(onStartRecordStep1()));
connect(this, SIGNAL(StartRecordSignal()), m_Imager, SLOT(start_record()));
connect(this, SIGNAL(RecordWhiteSignal()), m_Imager, SLOT(record_white()));
connect(this, SIGNAL(RecordDarlSignal()), m_Imager, SLOT(record_dark()));
connect(m_Imager, SIGNAL(RecordWhiteFinishSignal()), this, SLOT(recordWhiteFinish()));
connect(m_Imager, SIGNAL(RecordDarlFinishSignal()), this, SLOT(recordDarkFinish()));
// Connect LayerFileCreated from imager to HPPA slot
connect(m_Imager, SIGNAL(LayerFileCreated(QString,QString,int)), this, SLOT(onLayerCreatedFromFile(QString,QString,int)));
connect(this->ui.actionOpenDirectory, SIGNAL(triggered()), this, SLOT(onActionOpenDirectory()));
connect(this->ui.framerate_lineEdit, SIGNAL(editingFinished()), this, SLOT(OnFramerateLineeditEditingFinished()));
connect(this->ui.FramerateSlider, SIGNAL(valueChanged(double)), this, SLOT(OnFramerateSliderChanged(double)));
connect(this->ui.integratioin_time_lineEdit, SIGNAL(editingFinished()), this, SLOT(OnIntegratioinTimeEditingFinished()));
connect(this->ui.IntegratioinTimeSlider, SIGNAL(valueChanged(double)), this, SLOT(OnIntegratioinTimeSliderChanged(double)));
connect(this->ui.gain_lineEdit, SIGNAL(editingFinished()), this, SLOT(OnGainEditingFinished()));
connect(this->ui.GainSlider, SIGNAL(valueChanged(double)), this, SLOT(OnGainSliderChanged(double)));
//相机参数控件设置为可用 + 输入控制
frame_number->setEnabled(true);
ui.framerate_lineEdit->setEnabled(true);
ui.integratioin_time_lineEdit->setEnabled(true);
ui.gain_lineEdit->setEnabled(true);
ui.FramerateSlider->setEnabled(true);
ui.IntegratioinTimeSlider->setEnabled(true);
ui.GainSlider->setEnabled(true);
/*QRegExp rx("\\d{0,3}[1-9]$");
ui.framerate_lineEdit->setValidator(new QRegExpValidator(rx));
frame_number->setValidator(new QRegExpValidator(rx));
ui.integratioin_time_lineEdit->setValidator(new QRegExpValidator(rx));
ui.gain_lineEdit->setValidator(new QRegExpValidator(rx));*/
//获取相机参数并显示到界面中
ui.framerate_lineEdit->setText(QString::number(m_Imager->getFramerate(), 10, 2));
ui.FramerateSlider->setValue(m_Imager->getFramerate(), true);
CalculateIntegratioinTimeRange();
ui.integratioin_time_lineEdit->setText(QString::number(m_Imager->getIntegrationTime(), 10, 2));
ui.IntegratioinTimeSlider->setValue(m_Imager->getIntegrationTime());
ui.gain_lineEdit->setText(QString::number(m_Imager->getGain(), 10, 2));
ui.GainSlider->setValue(m_Imager->getGain());
}
catch (std::exception const& e)
{
std::cerr << "Error: " << e.what() << std::endl;
delete m_Imager;
m_Imager = nullptr;
QMessageBox msgBox;
msgBox.setText(QString::fromLocal8Bit("请连接相机!"));
msgBox.exec();
}
}
void HPPA::testImagerStatus()
{
m_TestImagerStausThread->start();
}
void HPPA::onImageFileSaved(QString path, int fileIndex)
{
// 该槽在 UI 线程中执行Qt 会使用 queued connection可以安全操作 model
QFileInfo fi(path);
QString base = fi.completeBaseName(); // 去掉路径与扩展名(例如 tmp_image_0
// 将新的 layer 添加到 Raster 分组
if (!m_LayerTreeModel || !m_RasterGroup) return;
// layer 名称可根据需要调整,这里用文件名作为图层名
{
auto* ln = new LayerTreeLayerNode(nullptr);
ln->setName(base);
m_LayerTreeModel->addLayer(m_RasterGroup, ln);
}
// 可选:展开 TOC 或者做其他 UI 更新(目前不做动画,仅打印日志)
qDebug() << "ImageFileSaved -> add layer:" << base << " index:" << fileIndex;
}
void HPPA::onAutoExposure()
{
double ReturnedExposureTime = m_Imager->auto_exposure();
//将自动曝光所得的值显示到界面
ui.IntegratioinTimeSlider->setValue(ReturnedExposureTime, false);
ui.mainToolBar->widgetForAction(ui.action_auto_exposure)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
//ui.mainToolBar->widgetForAction(ui.action_auto_exposure)->setStyleSheet("QLineEdit{background-color:rgb(255,255,255);}");
}
void HPPA::onFocus1()
{
focusWindow* w = new focusWindow(this, m_Imager);
connect(w, SIGNAL(StartManualFocusSignal(int)), this, SLOT(onFocus2(int)));
//w->setModal(true);//设置窗口为模态:只能操作当前窗口
w->show();
w->exec();
//disconnect(w, SIGNAL(StartManualFocusSignal(int)), this, SLOT(onFocus2(int)));
}
void HPPA::onFocus2(int command)
{
if (command == 1)
{
//创建影像显示窗口
QWidget* tabTmp = new QWidget();
QGridLayout* GridLayout = new QGridLayout();
GridLayout->addWidget(new Mapcavas(tabTmp));
tabTmp->setLayout(GridLayout);
m_imageViewerTabWidget->addTab(tabTmp, QString::fromLocal8Bit("调焦"));
//m_imageViewerTabWidget->setCurrentIndex(trackNumber);
m_imageViewerTabWidget->setCurrentWidget(tabTmp);
//开始调焦
emit StartFocusSignal();
}
else if (command == 0)
{
m_Imager->setFocusControlState(false);
}
}
void HPPA::onAbout()
{
aboutWindow about;
about.show();
about.exec();
}
void HPPA::onDark()
{
QMessageBox msgBox;
msgBox.setText(QString::fromLocal8Bit("采集暗电流,请确保镜头盖盖上!"));
msgBox.exec();
QAction* checked = moveplatformActionGroup->checkedAction();
QString checkedName = checked->objectName();
if (checkedName == "mAction_is_no_motor" || checkedName == "mAction_RobotArm")
{
emit RecordDarlSignal();
}
else if (checkedName == "mAction_1AxisMotor")
{
m_omc->setImager(m_Imager);
m_omc->record_dark();
}
else if (checkedName == "mAction_2AxisMotor_new")
{
m_tmc->setImager(m_Imager);
m_tmc->record_dark();
return;
}
}
void HPPA::recordDarkFinish()
{
ui.mainToolBar->widgetForAction(ui.action_dark)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
}
void HPPA::onReference()
{
QMessageBox msgBox;
msgBox.setText(QString::fromLocal8Bit("请确保白板放置正确!"));
msgBox.exec();
QAction* checked = moveplatformActionGroup->checkedAction();
QString checkedName = checked->objectName();
if (checkedName == "mAction_is_no_motor" || checkedName == "mAction_RobotArm")
{
emit RecordWhiteSignal();
}
else if (checkedName == "mAction_1AxisMotor")
{
m_omc->setImager(m_Imager);
m_omc->record_white();
}
else if (checkedName == "mAction_2AxisMotor_new")
{
m_tmc->setImager(m_Imager);
m_tmc->record_white();
return;
}
}
void HPPA::recordWhiteFinish()
{
ui.mainToolBar->widgetForAction(ui.action_reference)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
}
void HPPA::onPlotHyperspectralImageRgbImage(int fileNumber, int frameNumber, QString filePath)
{
//使用机械臂采集时,会在停止采集后的瞬间又开始采集,会导致上次采集最后发射的信号调用此槽函数报错
QAction* checked = moveplatformActionGroup->checkedAction();
QString checkedName = checked->objectName();
if (frameNumber == -1 && checkedName == "mAction_RobotArm")
{
return;
}
//return;
//获取绘图控件
QWidget* currentWidget = m_MapLayerStore->widgetForLayer(filePath);
//QWidget* currentWidget = m_imageViewerTabWidget->widget(fileNumber);
QList<Mapcavas*> currentImageViewer = currentWidget->findChildren<Mapcavas*>();
currentImageViewer[0]->DisplayFrameNumber(m_Imager->getFrameCounter());//界面中显示已经采集的帧数
//创建需要显示的图像--opencv版本
ImageProcessor imageProcessor;
//cv::Mat rgbImage(*m_Imager->getRgbImage()->m_matRgbImage, cv::Range(0, m_Imager->getFrameCounter()), cv::Range::all());//2022.3.18重构的
cv::Mat rgbImage(*m_Imager->getMatRgbImage(), cv::Range(0, m_Imager->getFrameCounter()), cv::Range::all());
cv::Mat rgbImageStretched = imageProcessor.CStretch(rgbImage, 0.02);
//在界面中显示图像
currentImageViewer[0]->SetImage(&QPixmap::fromImage(imageProcessor.Mat2QImage(rgbImageStretched)));//绘制图像
//20241225
//保存拉伸后的rgb
//FileOperation* fileOperation = new FileOperation();
//string directory = fileOperation->getDirectoryOfExe();
//string rgbFilePathNoStrech = directory + "\\tmp_image_no_strech.png";//未拉伸图片
//string rgbFilePathStrech = directory + "\\tmp_image_strech.png";//拉伸图片
//cv::imwrite(rgbFilePathNoStrech, rgbImage);
//cv::imwrite(rgbFilePathStrech, rgbImageStretched);
//创建需要显示的图像--qt版本
//QRect CuttedRect = m_Imager->getRgbImage()->m_matRgbImage->rect();//先获取image整个rect
//CuttedRect.setHeight(m_Imager->getFrameCounter() - 1);//裁剪rect
//QImage CuttedImage = m_Imager->getRgbImage()->m_matRgbImage->copy(CuttedRect);
//currentImageViewer[0]->SetImage(&QPixmap::fromImage(CuttedImage));//绘制图像
}
void HPPA::PlotSpectral(int state)
{
if (state == 1)
{
//显示影像
QWidget* currentWidget = m_imageViewerTabWidget->currentWidget();
QList<Mapcavas*> currentImageViewer = currentWidget->findChildren<Mapcavas*>();
currentImageViewer[0]->DisplayFrameNumber(m_Imager->getFocusFrameCounter());//界面中显示已经采集的帧数
ImageProcessor imageProcessor;
//cv::Mat grayImage(*m_Imager->getRgbImage()->m_matFocusGrayImage, cv::Range::all(), cv::Range::all());//2022.3.18重构的
//cv::Mat grayImage(*m_Imager->getMatFocusGrayImage(), cv::Range::all(), cv::Range::all());
//currentImageViewer[0]->SetImage(&QPixmap::fromImage(imageProcessor.Mat2QImage(grayImage)));//绘制图像
currentImageViewer[0]->SetImage(&QPixmap::fromImage(m_Imager->getQImageFocusGrayImage()));//绘制图像
//绘制光谱
QLineSeries* series = new QLineSeries();
//series->clear();//////////////////////////////
int sampleCount = m_Imager->getSampleCount();
for (size_t i = 0; i < sampleCount; i++)
{
//malloc申请的内存用法1可以当做数组用
//series->append(i, m_Imager->buffer[i + 5 * 900]);
//series->append(i, m_Imager->buffer[900 * 150 + i]);
series->append(i, m_Imager->buffer[1368 * 150 + i]);
}
QChart* chart = new QChart();
chart->legend()->hide();
chart->addSeries(series);
chart->createDefaultAxes();
//chart->setTitle("Simple line chart example");
m_chartView->setChart(chart);
}
else
{
//改变界面上的按钮文字
}
////显示影像
//QWidget* currentWidget = m_imageViewerTabWidget->currentWidget();
//QList<ImageViewer *> currentImageViewer = currentWidget->findChildren<ImageViewer *>();
//
//ImageProcessor imageProcessor;
//
////绘制光谱
//QLineSeries *series = new QLineSeries();
////series->clear();//////////////////////////////
//int sampleCount = m_Imager->getSampleCount();
//
//QChart *chart = new QChart();
//chart->legend()->hide();
//chart->addSeries(series);
//chart->createDefaultAxes();
////chart->setTitle("Simple line chart example");
//m_chartView->setChart(chart);
//while (state)
//{
// currentImageViewer[0]->DisplayFrameNumber(m_Imager->getFocusFrameCounter());//界面中显示已经采集的帧数
// cv::Mat grayImage(*m_Imager->getMatFocusGrayImage(), cv::Range::all(), cv::Range::all());
// currentImageViewer[0]->SetImage(&QPixmap::fromImage(imageProcessor.Mat2QImage(grayImage)));//绘制图像
// for (size_t i = 0; i < sampleCount; i++)
// {
// //malloc申请的内存用法1可以当做数组用
// //series->append(i, m_Imager->buffer[i + 5 * 900]);
// series->append(i, m_Imager->buffer[900 * 150 + i]);
// }
// std::cout << "-----------------------------------------------" << std::endl;
//}
}
void HPPA::onRecordFinishedSignal_WhenFrameNumberMeet()
{
QAction* checked = moveplatformActionGroup->checkedAction();
QString checkedName = checked->objectName();
std::cout << "停止采集原因:帧数采集完了。" << std::endl;
ui.action_start_recording->setText(QString::fromLocal8Bit("采集"));
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
m_RecordState++;//当自动停止采集
}
void HPPA::onRecordFinishedSignal_WhenFrameNumberNotMeet()
{
QAction* checked = moveplatformActionGroup->checkedAction();
QString checkedName = checked->objectName();
if (checkedName == "mAction_RobotArm")//机械臂会在停止采集后的瞬间又开始采集导致ui.action_start_recording显示异常
{
return;
}
if (checkedName == "mAction_2AxisMotor_new")//会有多条采集线,中间的某条采集线完成后不代表整个采集过程完成
{
return;
}
std::cout << "停止采集原因1帧数没有采集够时马达到达最大位置2手动停止采集。" << std::endl;
ui.action_start_recording->setText(QString::fromLocal8Bit("采集"));
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
m_RecordState++;
}
void HPPA::onsequenceComplete()
{
ui.action_start_recording->setText(QString::fromLocal8Bit("采集"));
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
m_RecordState++;
}
WorkerThread3::WorkerThread3(CFocusMotorControl* ctrlFocusMotor)
{
m_ctrlFocusMotor = ctrlFocusMotor;
}
void WorkerThread3::run()
{
m_ctrlFocusMotor->StartAutoFocus(820, 910, 20, 2);
emit AutoFocusFinishedSignal();
}
void HPPA::onLayerCreatedFromFile(const QString& baseName, const QString& filePath, int fileIndex)
{
if (!m_LayerTreeModel || !m_RasterGroup) return;
QWidget* mapcavasContainer = onCreateTab(baseName);
// Create MapLayer first and attach it to a LayerTreeLayerNode
RasterLayer* ml = new RasterLayer(baseName, filePath);
if (m_MapLayerStore) m_MapLayerStore->addLayer(ml, mapcavasContainer);
QList<Mapcavas*> mapcavas = mapcavasContainer->findChildren<Mapcavas*>();
mapcavas[0]->setLayers(ml);
auto* layerNode = new LayerTreeLayerNode(ml);
LayerTreeNode* node = m_LayerTreeModel->addLayer(m_RasterGroup, layerNode);
LayerTreeLayerNode* lnode = dynamic_cast<LayerTreeLayerNode*>(node);
if (!lnode) return;
// layerNode already holds the MapLayer pointer from constructor
qDebug() << "LayerFileCreated -> created layer:" << baseName << "path:" << filePath << "index:" << fileIndex;
}
void HPPA::onLayerTreeSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected)
{
Q_UNUSED(deselected);
if (selected.indexes().isEmpty()) {
m_ic->setActiveLayer(nullptr);
return;
}
QModelIndex idx = selected.indexes().first();
if (!idx.isValid()) {
m_ic->setActiveLayer(nullptr);
return;
}
LayerTreeNode* node = static_cast<LayerTreeNode*>(idx.internalPointer());
if (!node || node->type() != LayerTreeNode::Type::Layer) {
m_ic->setActiveLayer(nullptr);
return;
}
auto* layerNode = static_cast<LayerTreeLayerNode*>(node);
MapLayer* mapLayer = layerNode->mapLayer();
if (!mapLayer || mapLayer->layerType() != MapLayer::LayerType::Raster) {
m_ic->setActiveLayer(nullptr);
return;
}
RasterLayer* rl = static_cast<RasterLayer*>(mapLayer);
m_ic->setActiveLayer(rl);
// Also switch to the corresponding tab in the image viewer
if (m_MapLayerStore && m_imageViewerTabWidget) {
QWidget* widget = m_MapLayerStore->widgetForLayer(mapLayer);
if (widget) {
int tabIndex = m_imageViewerTabWidget->indexOf(widget);
if (tabIndex >= 0) {
m_imageViewerTabWidget->setCurrentIndex(tabIndex);
}
}
}
}
void HPPA::onBandSelectionChanged(double rWave, double gWave, double bWave)
{
RasterLayer* rl = m_ic->activeLayer();
if (!rl) return;
// Find the Mapcavas widget associated with this layer and re-render
if (!m_MapLayerStore) return;
QWidget* container = m_MapLayerStore->widgetForLayer(rl);
if (!container) return;
QList<Mapcavas*> mapcavas = container->findChildren<Mapcavas*>();
if (mapcavas.isEmpty()) return;
RasterLayer::RenderParams params = rl->currentRenderParams();
params.rWave = rWave;
params.gWave = gWave;
params.bWave = bWave;
rl->setCurrentRenderParams(params);
mapcavas[0]->freshmap(params);
}