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();
}
相关推荐
Geek之路4 小时前
Qt系统学习篇(6)-QMainWindow
数据库·qt·学习
初阳7855 小时前
【Qt】控件概述(2)—— 按钮类控件
开发语言·qt
初阳7855 小时前
【Qt】控件概述(3)—— 显示类控件
开发语言·qt
efls1116 小时前
Qt_绘图
开发语言·c++·qt
TravisBytes6 小时前
在 Qt 项目中使用 spdlog 的全攻略
开发语言·c++·qt
code_snow7 小时前
QT学习笔记4.5(文件、参数文件)
笔记·qt·学习
海绵波波1071 天前
梗百科——信号和槽机制
qt
code_snow1 天前
QT学习笔记1.2(QT的应用)
笔记·qt·学习
code_snow1 天前
QT学习笔记3.1(建立项目、执行_建立第一个工程)
qt
冰红茶兑滴水1 天前
Qt 概述
开发语言·qt