QGraphicsView实现简易地图16『爆炸效果』

前文链接:QGraphicsView实现简易地图15『测量面积』
一种简单的爆炸波扩散效果
动态演示效果:

静态展示图片:

核心代码:

cpp 复制代码
#pragma once
#include "../AbstractGeoItem.h"
#include "DataStruct/GeoData.h"

/*
 * 爆炸扩散效果-静态
 */

class ExplosiveDiffusionItem : public AbstractGeoItem
{
public:
	ExplosiveDiffusionItem(const GeoCoord &geoCoord, int radius, QGraphicsItem *parent = nullptr);
	~ExplosiveDiffusionItem();

	// 更新地理位置
	virtual void updateGeoPos();

protected:
	virtual QRectF boundingRect() const override;
	virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;

	// 设置半径(单位:米)
	void setRadius(int radius);
	// 获取半径(单位:米)
	int radius();

protected:
	int m_radius;	// 半径(单位:米)
	double m_rw;	// 基于指定经纬度处的椭圆横轴半径
	double m_rh;	// 基于指定经纬度处的椭圆竖轴半径
};
cpp 复制代码
#include "ExplosiveDiffusionItem.h"
#include <QRadialGradient>
#include <QPainter>
#include "Utility/MapUtility.h"

ExplosiveDiffusionItem::ExplosiveDiffusionItem(const GeoCoord &geoCoord, int radius, QGraphicsItem *parent /*= nullptr*/) : AbstractGeoItem(parent)
{
	setZValue(300);
	setGeoPos(geoCoord.lon, geoCoord.lat);
	m_radius = radius;
}

ExplosiveDiffusionItem::~ExplosiveDiffusionItem()
{

}

void ExplosiveDiffusionItem::updateGeoPos()
{
	AbstractGeoItem::updateGeoPos();
	prepareGeometryChange();
}

QRectF ExplosiveDiffusionItem::boundingRect() const
{
	return QRectF(-m_rw, -m_rh, 2 * m_rw, 2 * m_rh);
}

void ExplosiveDiffusionItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
	QRadialGradient gr(0, 0, m_rw, 0, 0);
	gr.setColorAt(0.0, QColor(255, 255, 255, 0));
	gr.setColorAt(0.90, QColor(255, 255, 255, 10));
	gr.setColorAt(0.94, QColor(255, 255, 255, 40));
	gr.setColorAt(0.99, QColor(185, 225, 240, 255));
	gr.setColorAt(1, QColor(185, 225, 240, 128));

	painter->setRenderHint(QPainter::Antialiasing);
	painter->setBrush(gr);
	painter->setPen(Qt::NoPen);
	painter->drawEllipse(boundingRect());
}

void ExplosiveDiffusionItem::setRadius(int radius)
{
	m_radius = radius;

	GeoCoord right = MapUtility::geoCoordByDisAndBearing(m_lon, m_lat, 90, m_radius);
	GeoCoord top = MapUtility::geoCoordByDisAndBearing(m_lon, m_lat, 0, m_radius);

	QPointF rightPos = sceneCoordFromGeoCoord(right.lon, right.lat);
	QPointF topPos = sceneCoordFromGeoCoord(top.lon, top.lat);
	QPointF centerPos = sceneCoordFromGeoCoord(m_lon, m_lat);
	m_rw = rightPos.x() - centerPos.x();
	m_rh = centerPos.y() - topPos.y();

	prepareGeometryChange();
}

int ExplosiveDiffusionItem::radius()
{
	return m_radius;
}

此处提供的动态效果,是利用QPropertyAnimation制作而成,后面文章的动态效果也是采用这种方法,后续将不再展示代码,参考此处即可。

cpp 复制代码
#pragma once
#include "ExplosiveDiffusionItem.h"

/*
 * 爆炸扩散效果-动态扩散
 */

class QPropertyAnimation;

class ExplosiveDiffusionAnimateItem : public QObject, public ExplosiveDiffusionItem
{
	Q_OBJECT
	Q_PROPERTY(int m_radius WRITE setRadius READ radius)

public:
	ExplosiveDiffusionAnimateItem(const GeoCoord &geoCoord, int radius, QGraphicsItem *parent = nullptr);
	~ExplosiveDiffusionAnimateItem();

	void start(int msecs = 1000);

private:
	QPropertyAnimation *m_animation;
};
cpp 复制代码
#include "ExplosiveDiffusionAnimateItem.h"
#include <QPropertyAnimation>

ExplosiveDiffusionAnimateItem::ExplosiveDiffusionAnimateItem(const GeoCoord &geoCoord, int radius, QGraphicsItem *parent /*= nullptr*/)
	: ExplosiveDiffusionItem(geoCoord, radius, parent)
{
	m_animation = new QPropertyAnimation(this, "m_radius", this);
	m_animation->setEasingCurve(QEasingCurve::InOutQuad);
	connect(m_animation, &QAbstractAnimation::finished, this, &ExplosiveDiffusionAnimateItem::finished);
}

ExplosiveDiffusionAnimateItem::~ExplosiveDiffusionAnimateItem()
{

}

void ExplosiveDiffusionAnimateItem::start(int msecs/* = 1000*/)
{
	if (m_animation->state() != QAbstractAnimation::Stopped)
		m_animation->stop();

	m_animation->setDuration(msecs);
	m_animation->setStartValue(0);
	m_animation->setEndValue(m_radius);
	m_animation->start();
}
相关推荐
xcyxiner7 小时前
DicomViewer (后台线程处理文件)4
qt
xcyxiner15 小时前
DicomViewer (添加模型类)3
qt
xcyxiner1 天前
DicomViewer (目录调整) 2
qt
xcyxiner1 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能3 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G3 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt
森G3 天前
77、线程池原理和实现------服务器源码解析----云视频服务项目
服务器·c++·qt
森G4 天前
71、打包发布---------打包发布
c++·qt
初圣魔门首席弟子4 天前
Node.js 详细介绍(知识库版)
windows·qt·node.js·知识库
C++ 老炮儿的技术栈4 天前
Qt工控实战:自研机器人TCP长连接客户端(粘包处理+心跳保活+自动重连完整源码解析)
qt·tcp/ip·机器人