完成maptool的功能:

1、工具在工具栏中的状态管理;
2、工具在mapcavas中的图标管理;
3、工具在多tab切换时的管理;
4、MapToolSpectral添加十字叉,显示点击位置;
This commit is contained in:
tangchao0503
2026-03-13 11:12:00 +08:00
parent 741e0e6734
commit 1c7780eb14
7 changed files with 142 additions and 99 deletions

View File

@ -91,7 +91,7 @@ HPPA::HPPA(QWidget* parent)
ui.splitter->setStretchFactor(2, 3);*/ ui.splitter->setStretchFactor(2, 3);*/
initMenubarToolbar(); initMenubarToolbar();
initMapTools();
//光谱仪操作 //光谱仪操作
m_Imager = nullptr; m_Imager = nullptr;
m_RecordState = 0; m_RecordState = 0;
@ -122,7 +122,7 @@ HPPA::HPPA(QWidget* parent)
//connect(ui.graphicsView->imager, SIGNAL(leftMouseButtonPressed(int, int)), this, SLOT(onimagerSimulatorMove(int, int))); //connect(ui.graphicsView->imager, SIGNAL(leftMouseButtonPressed(int, int)), this, SLOT(onimagerSimulatorMove(int, int)));
initPanelToolbar(); initPanelToolbar();
initMapTools();
setDockNestingEnabled(true); setDockNestingEnabled(true);
connect(this->ui.action_about, SIGNAL(triggered()), this, SLOT(onAbout())); connect(this->ui.action_about, SIGNAL(triggered()), this, SLOT(onAbout()));
connect(this->ui.mActionOneMotorScenario, SIGNAL(triggered()), this, SLOT(createOneMotorScenario())); connect(this->ui.mActionOneMotorScenario, SIGNAL(triggered()), this, SLOT(createOneMotorScenario()));
@ -579,6 +579,8 @@ sizePolicy1.setHeightForWidth(graphicsView_delete->sizePolicy().hasHeightForWidt
ui.mDockWidgetSimulator->setFeatures(QDockWidget::DockWidgetClosable); ui.mDockWidgetSimulator->setFeatures(QDockWidget::DockWidgetClosable);
initMapTools();
QString strPath = QCoreApplication::applicationDirPath() + "/UILayout.ini"; QString strPath = QCoreApplication::applicationDirPath() + "/UILayout.ini";
QFile file(strPath); QFile file(strPath);
if (file.open(QIODevice::ReadOnly)) 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_connect_imager->setIcon(QIcon(".//icon//all//connect_imager.png"));
ui.action_auto_exposure->setIcon(QIcon(".//icon//all//exposure.png")); ui.action_auto_exposure->setIcon(QIcon(".//icon//all//exposure.png"));
ui.action_focus->setIcon(QIcon(".//icon//all//focus.png")); ui.action_focus->setIcon(QIcon(".//icon//all//focus.png"));
ui.action_dark->setIcon(QIcon(".//icon//all//dark.png")); ui.action_dark->setIcon(QIcon(".//icon//all//dark.png"));
ui.action_reference->setIcon(QIcon(".//icon//all//reference.png")); ui.action_reference->setIcon(QIcon(".//icon//all//reference.png"));
// 使用样式表设置透明背景 // 使用样式表设置透明背景
toolBar->setStyleSheet(R"( toolBar->setStyleSheet(R"(
@ -1010,6 +1012,11 @@ void HPPA::initMapTools()
ui.mActionPan->setCheckable(true); ui.mActionPan->setCheckable(true);
ui.mActionSpectral->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 = new MapTools(this);
m_mapTools->mapToolPan()->setAction(ui.mActionPan); m_mapTools->mapToolPan()->setAction(ui.mActionPan);
m_mapTools->mapToolSpectral()->setAction(ui.mActionSpectral); m_mapTools->mapToolSpectral()->setAction(ui.mActionSpectral);
@ -1021,51 +1028,28 @@ void HPPA::initMapTools()
connect(ui.mActionSpectral, SIGNAL(triggered()), this, SLOT(onMapToolSpectralTriggered())); connect(ui.mActionSpectral, SIGNAL(triggered()), this, SLOT(onMapToolSpectralTriggered()));
// Default tool: pan // Default tool: pan
//ui.mActionPan->trigger(); ui.mActionPan->trigger();
} }
void HPPA::onMapToolPanTriggered() void HPPA::onMapToolPanTriggered()
{ {
// Find the current Mapcavas m_mapTools->setActiveTool(m_mapTools->mapToolPan());
QWidget* currentWidget = m_imageViewerTabWidget->currentWidget(); setMapTool();
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() void HPPA::onMapToolSpectralTriggered()
{ {
// Find the current Mapcavas m_mapTools->setActiveTool(m_mapTools->mapToolSpectral());
QWidget* currentWidget = m_imageViewerTabWidget->currentWidget(); setMapTool();
if (!currentWidget) return; }
QList<Mapcavas*> canvases = currentWidget->findChildren<Mapcavas*>(); void HPPA::setMapTool()
if (canvases.isEmpty()) return; {
int tmp = m_imageViewerTabWidget->count();
if (tmp == 0) return;
Mapcavas* canvas = canvases[0]; int currentIndex = m_imageViewerTabWidget->currentIndex();
onTabWidgetCurrentChanged(currentIndex);
// Set canvas on shared tool and activate
m_mapTools->setMapcavas(canvas);
// Uncheck the other action
ui.mActionPan->setChecked(false);
canvas->setMapTool(m_mapTools->mapToolSpectral());
} }
//---------------------------------------------------- //----------------------------------------------------
@ -1266,7 +1250,7 @@ void HPPA::onStartRecordStep1()
m_RecordState -= 1; m_RecordState -= 1;
ui.action_start_recording->setText(QString::fromLocal8Bit("采集")); 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; return;
} }
@ -1341,21 +1325,14 @@ void HPPA::onTabWidgetCurrentChanged(int index)//代码新建一个tab会调
QWidget* currentWidget = m_imageViewerTabWidget->widget(index); QWidget* currentWidget = m_imageViewerTabWidget->widget(index);
QList<Mapcavas*> currentImageViewer = currentWidget->findChildren<Mapcavas*>(); QList<Mapcavas*> currentImageViewer = currentWidget->findChildren<Mapcavas*>();
//先disconnect然后再connect否则每次切换一次都会connect一次会累积connect很多次 // Re-apply the current active map tool to the new canvas
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]; Mapcavas* canvas = currentImageViewer[0];
m_mapTools->setMapcavas(canvas); m_mapTools->setMapcavas(canvas);
if (ui.mActionPan->isChecked()) MapTool* activeTool = m_mapTools->activeTool();
if (activeTool)
{ {
canvas->setMapTool(m_mapTools->mapToolPan()); canvas->setMapTool(activeTool);
}
else if (ui.mActionSpectral->isChecked())
{
canvas->setMapTool(m_mapTools->mapToolSpectral());
} }
} }

View File

@ -281,7 +281,9 @@ private:
// Map tools // Map tools
MapTools* m_mapTools = nullptr; MapTools* m_mapTools = nullptr;
QActionGroup* m_mapToolActionGroup = nullptr;
void initMapTools(); void initMapTools();
void setMapTool();
public Q_SLOTS: public Q_SLOTS:
void onPlotHyperspectralImageRgbImage(int fileNumber, int frameNumber, QString filePath); void onPlotHyperspectralImageRgbImage(int fileNumber, int frameNumber, QString filePath);

View File

@ -45,7 +45,6 @@ Mapcavas::Mapcavas(QWidget* pParent) :QGraphicsView(pParent)
m_translateSpeed = 1.0; m_translateSpeed = 1.0;
m_bMouseTranslate = false; m_bMouseTranslate = false;
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setFrameShape(QFrame::NoFrame); setFrameShape(QFrame::NoFrame);
@ -136,29 +135,9 @@ void Mapcavas::mousePressEvent(QMouseEvent *event)
if (m_mapTool) if (m_mapTool)
{ {
m_mapTool->canvasMousePressEvent(event); m_mapTool->canvasMousePressEvent(event);
QGraphicsView::mousePressEvent(event);
return; 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<int>(std::floor(scenePt.x()));
const int y = static_cast<int>(std::floor(scenePt.y()));
if (m_rasterLayer && m_rasterLayer->isValidPixel(x, y))
{
QVector<double> wavelengths;
QVector<double> spectrum;
if (m_rasterLayer->readPixelSpectrum(x, y, wavelengths, spectrum))
{
emit leftMouseButtonPressed(x, y, wavelengths, spectrum);
}
}
}
QGraphicsView::mousePressEvent(event); QGraphicsView::mousePressEvent(event);
} }
@ -167,16 +146,10 @@ void Mapcavas::mouseMoveEvent(QMouseEvent *event)
if (m_mapTool) if (m_mapTool)
{ {
m_mapTool->canvasMouseMoveEvent(event); m_mapTool->canvasMouseMoveEvent(event);
QGraphicsView::mousePressEvent(event);
return; 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); QGraphicsView::mousePressEvent(event);
} }
@ -185,11 +158,10 @@ void Mapcavas::mouseReleaseEvent(QMouseEvent *event)
if (m_mapTool) if (m_mapTool)
{ {
m_mapTool->canvasMouseReleaseEvent(event); m_mapTool->canvasMouseReleaseEvent(event);
QGraphicsView::mouseReleaseEvent(event);
return; return;
} }
// Legacy fallback
m_bMouseTranslate = false;
QGraphicsView::mouseReleaseEvent(event); QGraphicsView::mouseReleaseEvent(event);
} }

View File

@ -3,8 +3,13 @@
#include "ImageViewer.h" #include "ImageViewer.h"
#include "RasterLayer.h" #include "RasterLayer.h"
#include <QMouseEvent> #include <QMouseEvent>
#include <QGraphicsScene>
#include <QGraphicsLineItem>
#include <QPen>
#include <cmath> #include <cmath>
const double MapToolSpectral::CrosshairHalfLen = 10.0;
MapToolSpectral::MapToolSpectral(QObject* parent) MapToolSpectral::MapToolSpectral(QObject* parent)
: MapTool(parent) : MapTool(parent)
{ {
@ -13,6 +18,18 @@ MapToolSpectral::MapToolSpectral(QObject* parent)
MapToolSpectral::~MapToolSpectral() 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) void MapToolSpectral::canvasMousePressEvent(QMouseEvent* e)
@ -30,6 +47,9 @@ void MapToolSpectral::canvasMousePressEvent(QMouseEvent* e)
RasterLayer* rl = canvas()->rasterLayer(); RasterLayer* rl = canvas()->rasterLayer();
if (rl && rl->isValidPixel(x, y)) if (rl && rl->isValidPixel(x, y))
{ {
// Place crosshair at pixel center
updateCrosshair(x + 0.5, y + 0.5);
QVector<double> wavelengths; QVector<double> wavelengths;
QVector<double> spectrum; QVector<double> spectrum;
if (rl->readPixelSpectrum(x, y, wavelengths, 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;
}
}

View File

@ -4,6 +4,8 @@
#include "MapTool.h" #include "MapTool.h"
#include <QVector> #include <QVector>
class QGraphicsLineItem;
class MapToolSpectral : public MapTool class MapToolSpectral : public MapTool
{ {
Q_OBJECT Q_OBJECT
@ -14,8 +16,20 @@ public:
void canvasMousePressEvent(QMouseEvent* e) override; void canvasMousePressEvent(QMouseEvent* e) override;
void activate() override;
void deactivate() override;
signals: signals:
void spectralClicked(int x, int y, QVector<double> wavelengths, QVector<double> spectrum); void spectralClicked(int x, int y, QVector<double> wavelengths, QVector<double> 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 #endif // MAPTOOLSPECTRAL_H

View File

@ -6,39 +6,45 @@
MapTools::MapTools(QObject* parent) MapTools::MapTools(QObject* parent)
: QObject(parent) : QObject(parent)
{ {
m_mapToolPan = new MapToolPan(this); m_tools.insert(Pan, new MapToolPan(this));
m_mapToolSpectral = new MapToolSpectral(this); m_tools.insert(Spectral, new MapToolSpectral(this));
} }
MapTools::~MapTools() MapTools::~MapTools()
{ {
qDeleteAll(m_tools);
m_tools.clear();
} }
MapToolPan* MapTools::mapToolPan() const MapToolPan* MapTools::mapToolPan() const
{ {
return m_mapToolPan; return qobject_cast<MapToolPan*>(m_tools.value(Pan));
} }
MapToolSpectral* MapTools::mapToolSpectral() const MapToolSpectral* MapTools::mapToolSpectral() const
{ {
return m_mapToolSpectral; return qobject_cast<MapToolSpectral*>(m_tools.value(Spectral));
} }
MapTool* MapTools::mapTool(Tool tool) const MapTool* MapTools::mapTool(Tool tool) const
{ {
switch (tool) return m_tools.value(tool, nullptr);
{ }
case Pan:
return m_mapToolPan; MapTool* MapTools::activeTool() const
case Spectral: {
return m_mapToolSpectral; return m_activeTool;
default: }
return nullptr;
} void MapTools::setActiveTool(MapTool* tool)
{
m_activeTool = tool;
} }
void MapTools::setMapcavas(Mapcavas* canvas) void MapTools::setMapcavas(Mapcavas* canvas)
{ {
m_mapToolPan->setMapcavas(canvas); if (m_activeTool)
m_mapToolSpectral->setMapcavas(canvas); {
m_activeTool->setMapcavas(canvas);
}
} }

View File

@ -2,6 +2,7 @@
#define MAPTOOLS_H #define MAPTOOLS_H
#include <QObject> #include <QObject>
#include <QHash>
class MapTool; class MapTool;
class MapToolPan; class MapToolPan;
@ -27,11 +28,14 @@ public:
MapTool* mapTool(Tool tool) const; MapTool* mapTool(Tool tool) const;
MapTool* activeTool() const;
void setActiveTool(MapTool* tool);
void setMapcavas(Mapcavas* canvas); void setMapcavas(Mapcavas* canvas);
private: private:
MapToolPan* m_mapToolPan = nullptr; QHash<Tool, MapTool*> m_tools;
MapToolSpectral* m_mapToolSpectral = nullptr; MapTool* m_activeTool = nullptr;
}; };
#endif // MAPTOOLS_H #endif // MAPTOOLS_H