diff --git a/HPPA/HPPA.cpp b/HPPA/HPPA.cpp index df935e1..22ec195 100644 --- a/HPPA/HPPA.cpp +++ b/HPPA/HPPA.cpp @@ -91,7 +91,7 @@ HPPA::HPPA(QWidget* parent) ui.splitter->setStretchFactor(2, 3);*/ initMenubarToolbar(); - initMapTools(); + //光谱仪操作 m_Imager = nullptr; m_RecordState = 0; @@ -122,7 +122,7 @@ HPPA::HPPA(QWidget* parent) //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())); @@ -579,6 +579,8 @@ sizePolicy1.setHeightForWidth(graphicsView_delete->sizePolicy().hasHeightForWidt ui.mDockWidgetSimulator->setFeatures(QDockWidget::DockWidgetClosable); + initMapTools(); + QString strPath = QCoreApplication::applicationDirPath() + "/UILayout.ini"; QFile file(strPath); if (file.open(QIODevice::ReadOnly)) @@ -673,8 +675,8 @@ void HPPA::initMenubarToolbar() 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_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"( @@ -1010,6 +1012,11 @@ void HPPA::initMapTools() ui.mActionPan->setCheckable(true); ui.mActionSpectral->setCheckable(true); + m_mapToolActionGroup = new QActionGroup(this); + m_mapToolActionGroup->addAction(ui.mActionPan); + m_mapToolActionGroup->addAction(ui.mActionSpectral); + m_mapToolActionGroup->setExclusive(true); + m_mapTools = new MapTools(this); m_mapTools->mapToolPan()->setAction(ui.mActionPan); m_mapTools->mapToolSpectral()->setAction(ui.mActionSpectral); @@ -1021,51 +1028,28 @@ void HPPA::initMapTools() connect(ui.mActionSpectral, SIGNAL(triggered()), this, SLOT(onMapToolSpectralTriggered())); // Default tool: pan - //ui.mActionPan->trigger(); + ui.mActionPan->trigger(); } void HPPA::onMapToolPanTriggered() { - // Find the current Mapcavas - QWidget* currentWidget = m_imageViewerTabWidget->currentWidget(); - if (!currentWidget) - { - ui.mActionPan->setChecked(false); - return; - } - - QList canvases = currentWidget->findChildren(); - 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()); + m_mapTools->setActiveTool(m_mapTools->mapToolPan()); + setMapTool(); } void HPPA::onMapToolSpectralTriggered() { - // Find the current Mapcavas - QWidget* currentWidget = m_imageViewerTabWidget->currentWidget(); - if (!currentWidget) return; + m_mapTools->setActiveTool(m_mapTools->mapToolSpectral()); + setMapTool(); +} - QList canvases = currentWidget->findChildren(); - if (canvases.isEmpty()) return; +void HPPA::setMapTool() +{ + int tmp = m_imageViewerTabWidget->count(); + if (tmp == 0) 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()); + int currentIndex = m_imageViewerTabWidget->currentIndex(); + onTabWidgetCurrentChanged(currentIndex); } //---------------------------------------------------- @@ -1266,7 +1250,7 @@ void HPPA::onStartRecordStep1() 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);}"); + ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}"); } return; } @@ -1341,21 +1325,14 @@ void HPPA::onTabWidgetCurrentChanged(int index)//代码新建一个tab,会调 QWidget* currentWidget = m_imageViewerTabWidget->widget(index); QList currentImageViewer = currentWidget->findChildren(); - //先disconnect然后再connect,否则每次切换一次都会connect一次,会累积connect很多次! - disconnect(currentImageViewer[0], SIGNAL(leftMouseButtonPressed(int,int,QVector,QVector)), this, SLOT(onLeftMouseButtonPressed(int,int,QVector,QVector))); - connect(currentImageViewer[0], SIGNAL(leftMouseButtonPressed(int,int,QVector,QVector)), this, SLOT(onLeftMouseButtonPressed(int,int,QVector,QVector))); - - // Re-apply the current map tool to the new canvas + // Re-apply the current active map tool to the new canvas Mapcavas* canvas = currentImageViewer[0]; m_mapTools->setMapcavas(canvas); - if (ui.mActionPan->isChecked()) + MapTool* activeTool = m_mapTools->activeTool(); + if (activeTool) { - canvas->setMapTool(m_mapTools->mapToolPan()); - } - else if (ui.mActionSpectral->isChecked()) - { - canvas->setMapTool(m_mapTools->mapToolSpectral()); + canvas->setMapTool(activeTool); } } diff --git a/HPPA/HPPA.h b/HPPA/HPPA.h index 790b2ac..f027881 100644 --- a/HPPA/HPPA.h +++ b/HPPA/HPPA.h @@ -281,7 +281,9 @@ private: // Map tools MapTools* m_mapTools = nullptr; + QActionGroup* m_mapToolActionGroup = nullptr; void initMapTools(); + void setMapTool(); public Q_SLOTS: void onPlotHyperspectralImageRgbImage(int fileNumber, int frameNumber, QString filePath); diff --git a/HPPA/ImageViewer.cpp b/HPPA/ImageViewer.cpp index 2c8a27d..8203247 100644 --- a/HPPA/ImageViewer.cpp +++ b/HPPA/ImageViewer.cpp @@ -45,7 +45,6 @@ Mapcavas::Mapcavas(QWidget* pParent) :QGraphicsView(pParent) m_translateSpeed = 1.0; m_bMouseTranslate = false; - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setFrameShape(QFrame::NoFrame); @@ -136,29 +135,9 @@ void Mapcavas::mousePressEvent(QMouseEvent *event) if (m_mapTool) { m_mapTool->canvasMousePressEvent(event); + QGraphicsView::mousePressEvent(event); return; } - - // Legacy fallback when no tool is set - if (event->button()==Qt::LeftButton) - { - m_bMouseTranslate = true; - m_lastMousePos = event->pos(); - - const QPointF scenePt = mapToScene(m_lastMousePos); - const int x = static_cast(std::floor(scenePt.x())); - const int y = static_cast(std::floor(scenePt.y())); - - if (m_rasterLayer && m_rasterLayer->isValidPixel(x, y)) - { - QVector wavelengths; - QVector spectrum; - if (m_rasterLayer->readPixelSpectrum(x, y, wavelengths, spectrum)) - { - emit leftMouseButtonPressed(x, y, wavelengths, spectrum); - } - } - } QGraphicsView::mousePressEvent(event); } @@ -167,16 +146,10 @@ void Mapcavas::mouseMoveEvent(QMouseEvent *event) if (m_mapTool) { m_mapTool->canvasMouseMoveEvent(event); + QGraphicsView::mousePressEvent(event); return; } - // Legacy fallback - if (m_bMouseTranslate){ - QPointF mouseDelta = mapToScene(event->pos()) - mapToScene(m_lastMousePos); - translate(mouseDelta.x(),mouseDelta.y()); - } - - m_lastMousePos = event->pos(); QGraphicsView::mousePressEvent(event); } @@ -185,11 +158,10 @@ void Mapcavas::mouseReleaseEvent(QMouseEvent *event) if (m_mapTool) { m_mapTool->canvasMouseReleaseEvent(event); + QGraphicsView::mouseReleaseEvent(event); return; } - // Legacy fallback - m_bMouseTranslate = false; QGraphicsView::mouseReleaseEvent(event); } diff --git a/HPPA/MapToolSpectral.cpp b/HPPA/MapToolSpectral.cpp index f61fe33..6d9978b 100644 --- a/HPPA/MapToolSpectral.cpp +++ b/HPPA/MapToolSpectral.cpp @@ -3,8 +3,13 @@ #include "ImageViewer.h" #include "RasterLayer.h" #include +#include +#include +#include #include +const double MapToolSpectral::CrosshairHalfLen = 10.0; + MapToolSpectral::MapToolSpectral(QObject* parent) : MapTool(parent) { @@ -13,6 +18,18 @@ MapToolSpectral::MapToolSpectral(QObject* parent) MapToolSpectral::~MapToolSpectral() { + //removeCrosshair();//不需要在析构函数中调用removeCrosshair(),因为当MapToolSpectral被销毁时,它的canvas()也会被销毁,crosshair的scene也会被销毁,所以crosshair会自动被删除,不会造成内存泄漏。 +} + +void MapToolSpectral::activate() +{ + MapTool::activate(); +} + +void MapToolSpectral::deactivate() +{ + removeCrosshair(); + MapTool::deactivate(); } void MapToolSpectral::canvasMousePressEvent(QMouseEvent* e) @@ -30,6 +47,9 @@ void MapToolSpectral::canvasMousePressEvent(QMouseEvent* e) RasterLayer* rl = canvas()->rasterLayer(); if (rl && rl->isValidPixel(x, y)) { + // Place crosshair at pixel center + updateCrosshair(x + 0.5, y + 0.5); + QVector wavelengths; QVector spectrum; if (rl->readPixelSpectrum(x, y, wavelengths, spectrum)) @@ -38,3 +58,51 @@ void MapToolSpectral::canvasMousePressEvent(QMouseEvent* e) } } } + +void MapToolSpectral::updateCrosshair(double sceneX, double sceneY) +{ + if (!canvas() || !canvas()->scene()) + return; + + QGraphicsScene* scene = canvas()->scene(); + + QPen pen(Qt::red, 2.0); + pen.setCosmetic(true); // constant screen-width regardless of zoom + + if (!m_hLine) + { + m_hLine = scene->addLine(0, 0, 0, 0, pen); + m_hLine->setZValue(1e9); + } + if (!m_vLine) + { + m_vLine = scene->addLine(0, 0, 0, 0, pen); + m_vLine->setZValue(1e9); + } + + m_hLine->setPen(pen); + m_vLine->setPen(pen); + + m_hLine->setLine(sceneX - CrosshairHalfLen, sceneY, + sceneX + CrosshairHalfLen, sceneY); + m_vLine->setLine(sceneX, sceneY - CrosshairHalfLen, + sceneX, sceneY + CrosshairHalfLen); +} + +void MapToolSpectral::removeCrosshair() +{ + if (m_hLine) + { + if (m_hLine->scene()) + m_hLine->scene()->removeItem(m_hLine); + delete m_hLine; + m_hLine = nullptr; + } + if (m_vLine) + { + if (m_vLine->scene()) + m_vLine->scene()->removeItem(m_vLine); + delete m_vLine; + m_vLine = nullptr; + } +} diff --git a/HPPA/MapToolSpectral.h b/HPPA/MapToolSpectral.h index 6e4ca99..ebb62f1 100644 --- a/HPPA/MapToolSpectral.h +++ b/HPPA/MapToolSpectral.h @@ -4,6 +4,8 @@ #include "MapTool.h" #include +class QGraphicsLineItem; + class MapToolSpectral : public MapTool { Q_OBJECT @@ -14,8 +16,20 @@ public: void canvasMousePressEvent(QMouseEvent* e) override; + void activate() override; + void deactivate() override; + signals: void spectralClicked(int x, int y, QVector wavelengths, QVector spectrum); + +private: + void updateCrosshair(double sceneX, double sceneY); + void removeCrosshair(); + + QGraphicsLineItem* m_hLine = nullptr; // horizontal line + QGraphicsLineItem* m_vLine = nullptr; // vertical line + + static const double CrosshairHalfLen; }; #endif // MAPTOOLSPECTRAL_H diff --git a/HPPA/MapTools.cpp b/HPPA/MapTools.cpp index 991db1d..f0dbc5d 100644 --- a/HPPA/MapTools.cpp +++ b/HPPA/MapTools.cpp @@ -6,39 +6,45 @@ MapTools::MapTools(QObject* parent) : QObject(parent) { - m_mapToolPan = new MapToolPan(this); - m_mapToolSpectral = new MapToolSpectral(this); + m_tools.insert(Pan, new MapToolPan(this)); + m_tools.insert(Spectral, new MapToolSpectral(this)); } MapTools::~MapTools() { + qDeleteAll(m_tools); + m_tools.clear(); } MapToolPan* MapTools::mapToolPan() const { - return m_mapToolPan; + return qobject_cast(m_tools.value(Pan)); } MapToolSpectral* MapTools::mapToolSpectral() const { - return m_mapToolSpectral; + return qobject_cast(m_tools.value(Spectral)); } MapTool* MapTools::mapTool(Tool tool) const { - switch (tool) - { - case Pan: - return m_mapToolPan; - case Spectral: - return m_mapToolSpectral; - default: - return nullptr; - } + return m_tools.value(tool, nullptr); +} + +MapTool* MapTools::activeTool() const +{ + return m_activeTool; +} + +void MapTools::setActiveTool(MapTool* tool) +{ + m_activeTool = tool; } void MapTools::setMapcavas(Mapcavas* canvas) { - m_mapToolPan->setMapcavas(canvas); - m_mapToolSpectral->setMapcavas(canvas); + if (m_activeTool) + { + m_activeTool->setMapcavas(canvas); + } } diff --git a/HPPA/MapTools.h b/HPPA/MapTools.h index 83ea92b..bc03b75 100644 --- a/HPPA/MapTools.h +++ b/HPPA/MapTools.h @@ -2,6 +2,7 @@ #define MAPTOOLS_H #include +#include class MapTool; class MapToolPan; @@ -27,11 +28,14 @@ public: MapTool* mapTool(Tool tool) const; + MapTool* activeTool() const; + void setActiveTool(MapTool* tool); + void setMapcavas(Mapcavas* canvas); private: - MapToolPan* m_mapToolPan = nullptr; - MapToolSpectral* m_mapToolSpectral = nullptr; + QHash m_tools; + MapTool* m_activeTool = nullptr; }; #endif // MAPTOOLS_H