Qt开发带动画动态进度条控件(水波纹,圆形)

本文介绍了一种修复圆角进度条样式Bug的方法,并通过QVariantAnimation实现动画效果。此外,还展示了如何使用QPainter绘制带有平滑边缘的圆角进度条。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果图

在这里插入图片描述
核心代码
同时修复进度条圆角样式存在的bug

//动画部分
m_vAnimation = new QVariantAnimation(this);
if (m_vAnimation) {
	m_vAnimation->setDuration(2000);
	m_vAnimation->setKeyValueAt(0, 0.0);
	m_vAnimation->setKeyValueAt(0.5, 0.5);
	m_vAnimation->setKeyValueAt(1, 1.0);
	m_vAnimation->setLoopCount(-1);
	m_vAnimation->start();
	connect(m_vAnimation, &QVariantAnimation::valueChanged, this, &vProgressBars::sltAtIndexChanged);
}
void vProgressBars::sltAtIndexChanged(QVariant value)
{
	m_nAtIndex = value.toDouble();
	update();
}

//进度条绘制
void vProgressBars::paintEvent(QPaintEvent * event)
{
	QPainter painter(this);
	// 抗锯齿 + 平滑边缘处理
	painter.setRenderHints(QPainter::Antialiasing, true);
	painter.setRenderHints(QPainter::SmoothPixmapTransform, true);
	painter.setBrush(QBrush(QColor(255, 255, 255, 51)));
	painter.setPen(Qt::transparent);
	QRect rect = this->rect();
	int radius = rect.height() / 2;
	painter.drawRoundedRect(rect, radius, radius);

	QPainterPath draw_path;
	double percent = static_cast<double>(value()) / static_cast<double>(maximum());
	double x_move = (percent * width());
	double theta = acos(abs(x_move - radius) / radius);
	double y_move = (sin(theta) * radius);
	if (x_move <= radius) {
		draw_path.moveTo(x_move, radius - y_move);
		draw_path.arcTo(QRect(0, 0, radius * 2, radius * 2), static_cast<int>(180 - theta / M_PI * 180), static_cast<int>(theta / M_PI * 180));
		draw_path.arcTo(QRect(0, 0, radius * 2, radius * 2), 180, static_cast<int>(theta / M_PI * 180));
		draw_path.lineTo(static_cast<int>(x_move), static_cast<int>(radius - y_move));
	}
	else if (x_move < radius * 2) {
		draw_path.moveTo(radius, 0);
		draw_path.arcTo(QRect(0, 0, radius * 2, radius * 2), 90, 90);
		draw_path.arcTo(QRect(0, 0, radius * 2, radius * 2), 180, 90);
		draw_path.arcTo(QRect(0, 0, radius * 2, radius * 2), 270, static_cast<int>(90 - theta / M_PI * 180));
		draw_path.lineTo(static_cast<int>(x_move), static_cast<int>(radius - y_move));
		draw_path.arcTo(QRect(0, 0, radius * 2, radius * 2), 90 - static_cast<int>(90 - theta / M_PI * 180), static_cast<int>(90 - theta / M_PI * 180));
	}
	else {
		draw_path.moveTo(radius, 0);
		draw_path.arcTo(QRect(0, 0, radius * 2, radius * 2), 90, 90);
		draw_path.lineTo(0, height() - radius * 2);
		draw_path.arcTo(QRect(0, 0, radius * 2, radius * 2), 180, 90);
		draw_path.lineTo(percent*width() - radius * 2, height());
		draw_path.arcTo(QRect(static_cast<int>(percent*width()) - radius * 2, 0, radius * 2, radius * 2), 270, 90);
		draw_path.lineTo(percent*width(), radius * 2);
		draw_path.arcTo(QRect(static_cast<int>(percent*width() - radius * 2), 0, radius * 2, radius * 2), 0, 90);
		draw_path.lineTo(radius * 2, 0);
	}
	//整个进度条颜色
	//QLinearGradient linearGradient(rect.topLeft(), rect.topRight());
	//进度条部分颜色
	QLinearGradient linearGradient(QPoint(0, 0), QPoint(x_move, 0));
	linearGradient.setColorAt(1.0, QColor(255, 66, 213));
	linearGradient.setColorAt(m_nAtIndex, QColor(43, 74, 255));
	linearGradient.setColorAt(0.0, QColor(43, 74, 255));
	painter.fillPath(draw_path, QBrush(linearGradient));
}

源码传送门

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

离歌漠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值