前文链接:QGraphicsView实现简易地图13『平移与偏移-动画效果』
动态演示效果
静态展示图片
核心代码
#pragma once
#include <QObject>
#include "MapAbstractHandler.h"
#include "DataStruct/MeasureDistanceData.h"
/*
* 测距-工具类
*/
class MeasureDistanceHandler : public MapHandler<MeasureDistanceData>
{
Q_OBJECT
public:
MeasureDistanceHandler(const QString &name, QGraphicsView *parent, MeasureDistanceData *data);
~MeasureDistanceHandler();
static QString type() { return "MeasureDistanceHandler"; }
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
void connectHandlerToData(MeasureDistanceData *data) override;
void connectHandlerToView(MapView *view) override;
signals:
void addPointItem(const QString &handlerName, QGraphicsItem *item);
void addLineItem(const QString &handlerName, QGraphicsItem *item);
void clearItems();
void finished();
};
#include "MeasureDistanceHandler.h"
#include <QMouseEvent>
#include <QGraphicsScene>
#include "MapView/MapView.h"
#include "Utility/MapUtility.h"
#include "DataStruct/MapDataManager.h"
#include "DataStruct/EnumData.h"
#include "../Item/Custom/MeasureDistanceLineItem.h"
#include "../Item/Custom/MeasureDistancePointItem.h"
MeasureDistanceHandler::MeasureDistanceHandler(const QString &name, QGraphicsView *parent, MeasureDistanceData *data) : MapHandler(name, parent, data)
{
connectHandlerToData(data);
connectHandlerToView(dynamic_cast<MapView *>(m_view));
}
MeasureDistanceHandler::~MeasureDistanceHandler()
{
}
bool MeasureDistanceHandler::eventFilter(QObject *watched, QEvent *event)
{
if (watched == m_view)
{
if (event->type() == QEvent::MouseButtonPress)
{
QMouseEvent *ev = dynamic_cast<QMouseEvent *>(event);
// 鼠标左键取点(允许连续取点)
if (ev->button() == Qt::LeftButton)
{
m_view->setCursor(Qt::CrossCursor);
// 添加点
MeasureDistancePointItem *pointItem = new MeasureDistancePointItem;
QPointF scenePos = m_view->mapToScene(ev->pos());
GeoCoord geoCoord = MapUtility::geoCoordFromScene(scenePos, MapDataManager::instance()->mapLevel());
pointItem->setGeoPos(geoCoord.lon, geoCoord.lat);
pointItem->setZValue(QWHMapView::ML_MEASURE_POINT);
m_scene->addItem(pointItem);
// 添加线
if (m_data->pointCount(m_name) > 0)
{
MeasureDistancePointItem *lastPointItem = m_data->lastPoint(m_name);
GeoCoord geoCoord1(lastPointItem->lon(), lastPointItem->lat());
GeoCoord geoCoord2 = MapUtility::geoCoordFromScene(scenePos, MapDataManager::instance()->mapLevel());
MeasureDistanceLineItem *lineItem = new MeasureDistanceLineItem(geoCoord1.lon, geoCoord1.lat, geoCoord2.lon, geoCoord2.lat);
lineItem->setZValue(QWHMapView::ML_MEASURE_LINE);
m_scene->addItem(lineItem);
emit addLineItem(m_name, lineItem);
}
emit addPointItem(m_name, pointItem);
}
// 鼠标右键结束测距
else if (ev->button() == Qt::RightButton)
{
emit finished();
}
}
}
return MapHandler::eventFilter(watched, event);
}
void MeasureDistanceHandler::connectHandlerToData(MeasureDistanceData *data)
{
connect(this, &MeasureDistanceHandler::addPointItem, data, &MeasureDistanceData::onAddPointItem);
connect(this, &MeasureDistanceHandler::addLineItem, data, &MeasureDistanceData::onAddLineItem);
connect(this, &MeasureDistanceHandler::clearItems, data, &MeasureDistanceData::clearAllData);
}
void MeasureDistanceHandler::connectHandlerToView(MapView *view)
{
connect(this, &MeasureDistanceHandler::addPointItem, this, [view](const QString &handlerName, QGraphicsItem *item) {
view->addGeoItems(item);
});
connect(this, &MeasureDistanceHandler::addLineItem, this, [view](const QString &handlerName, QGraphicsItem *item) {
view->addGeoItems(item);
});
}