2155 lines
68 KiB
C++
2155 lines
68 KiB
C++
#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);
|
||
}
|