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();
}
相关推荐
feiyangqingyun1 小时前
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
c++·qt·udp·gb28181
jllws12 小时前
Qt学习及使用_第1部分_认识Qt---学习目的及技术准备
qt·c++框架
到点就困告2 小时前
海康工业相机SDK二次开发(VS+QT+海康SDK+C++)
数码相机·qt·海康
唐墨12314 小时前
android与Qt类比
android·开发语言·qt
道剑剑非道14 小时前
QT开发技术【ffmpeg + QAudioOutput】音乐播放器 完善
开发语言·qt·ffmpeg
不惑_15 小时前
用 PyQt5 打造一个可视化 JSON 数据解析工具
开发语言·qt·json
誰能久伴不乏1 天前
Qt 开发中的父类与父对象的区别和父对象传递:如何选择 `QWidget` 或 `QObject`?
java·开发语言·qt
誰能久伴不乏1 天前
理解继承与组合的本质:Qt 项目中的设计选择指南
开发语言·qt
抠脚学代码1 天前
Ubuntu18.6 学习QT问题记录以及虚拟机安装Ubuntu后的设置
qt·学习·ubuntu
小道士写程序2 天前
Qt 5.12 上读取 .xlsx 文件(Windows 平台)
开发语言·windows·qt