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();
}
相关推荐
嘤国大力士3 小时前
C++11&QT复习 (七)
java·c++·qt
嘤国大力士4 小时前
C++11&QT复习 (十一)
开发语言·c++·qt
wkm9564 小时前
qt.qpa.xcb: could not connect to display解决方法
开发语言·qt·ubuntu
追烽少年x7 小时前
在Qt中直接在构建目录下直接运行.exe文件报错问题分析
qt
AAA废品回收站陈师傅11 小时前
19信号和槽_信号和槽的基本概念
qt
爱吃巧克力的程序媛11 小时前
在 Qt 创建项目时,Qt Quick Application (Compat) 和 Qt Quick Application
开发语言·qt
AAA废品回收站陈师傅11 小时前
18认识Qt坐标系
qt
m0_5557629011 小时前
QT 动态布局实现(待完善)
服务器·数据库·qt
genispan12 小时前
QT/C++ 多线程并发下载实践
开发语言·c++·qt
努力搬砖的咸鱼13 小时前
Qt中的数据解析--XML与JSON处理全攻略
xml·开发语言·qt·json