完成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);*/
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<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());
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<Mapcavas*> canvases = currentWidget->findChildren<Mapcavas*>();
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);
}
//----------------------------------------------------
@ -1341,21 +1325,14 @@ void HPPA::onTabWidgetCurrentChanged(int index)//代码新建一个tab会调
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
// 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);
}
}

View File

@ -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);

View File

@ -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<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);
}
@ -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);
}

View File

@ -3,8 +3,13 @@
#include "ImageViewer.h"
#include "RasterLayer.h"
#include <QMouseEvent>
#include <QGraphicsScene>
#include <QGraphicsLineItem>
#include <QPen>
#include <cmath>
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<double> wavelengths;
QVector<double> 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 <QVector>
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<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

View File

@ -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<MapToolPan*>(m_tools.value(Pan));
}
MapToolSpectral* MapTools::mapToolSpectral() const
{
return m_mapToolSpectral;
return qobject_cast<MapToolSpectral*>(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);
}
}

View File

@ -2,6 +2,7 @@
#define MAPTOOLS_H
#include <QObject>
#include <QHash>
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<Tool, MapTool*> m_tools;
MapTool* m_activeTool = nullptr;
};
#endif // MAPTOOLS_H