Qt之模仿网易云音乐播放进度QNetEasyMusicSlider

12 篇文章 0 订阅

模仿网易云音乐播放进度条

通过重载PaintEvent函数来实现。首先画一条圆角矩形,然后根据滑块位置画出滑块。

环境

Qt5.6.2+Vs2013

效果

播放进度条

代码

QNetEasyMusicSlider类

QNetEasyMusicSlider.h

#pragma once

#include <QWidget>

class QNetEasyMusicSlider : public QWidget
{
	Q_OBJECT

public:
	QNetEasyMusicSlider(QWidget *parent);
	~QNetEasyMusicSlider();

public:
	void setStartValue(float value);

	float startValue() const;

	void setEndValue(float value);

	float endValue() const;

	public slots:
	void setCurrentPos(float value);

signals:
	void valueChanged(float value);

protected:
	void paintEvent(QPaintEvent *event);

	void mousePressEvent(QMouseEvent *event);

	void mouseReleaseEvent(QMouseEvent *event);

	void mouseMoveEvent(QMouseEvent *event);

private:
	void drawBg(QPainter* painter);

	void drawLine(QPainter* painter);

	void drawBlock(QPainter* painter);

	void initBackgroundColor();

private:
	QRectF x_rectLine;					//滑杆位置
	QRectF x_rectLeftLine;				//已播放滑杆位置
	QRectF x_rectRightLine;				//未播放滑杆位置
	QRectF x_rectBlock;

	QColor x_lineOverColor;				//已播放颜色
	QColor x_lineColor;					//未播放颜色

	int x_nLineHeight;					//滑竿高度
	int x_nBlockWidth;					//滑块的快读

	float x_fMinValue;					//最小值
	float x_fMaxValue;					//最大值
	float x_fValue;						//当前值
	float x_fScale;						//当前滑块比例

	QColor x_blackBorderColor;			//滑块边框颜色
	QColor x_blackCenterColor;			//滑块中心颜色
	QColor x_blackBgColor;				//滑块背景颜色

	int x_shdaowBorder;					//滑块选中阴影宽度

	QPoint x_pressedPos;
	bool x_bLBPressed;
	bool x_bBlackShadow;				//滑块阴影
};

QNetEasyMusicSlider.cpp

#include "NetEasyMusicSlider.h"

#include <QPainter>
#include <QStyleOption>
#include <qmath.h>
#include <QMouseEvent>
#include <QToolTip>

QNetEasyMusicSlider::QNetEasyMusicSlider(QWidget *parent)
	: QWidget(parent)
{
	setMouseTracking(true);
	setAttribute(Qt::WA_Hover, true);

	x_lineColor = QColor(194, 194, 196);
	x_lineOverColor = QColor(232, 60, 60);

	x_fValue = 0.0;
	x_nLineHeight = 4;
	x_nBlockWidth = 20;

	x_fMinValue = 0.0;
	x_fMaxValue = 100.0;

	x_fScale = 0.0;

	x_blackBorderColor = QColor(196, 196, 196);  //239,239,239
	x_blackCenterColor = QColor(Qt::red);
	x_blackBgColor = QColor(Qt::white);

	x_shdaowBorder = 4;
	x_bBlackShadow = false;

	x_bLBPressed = false;
}

QNetEasyMusicSlider::~QNetEasyMusicSlider()
{
}

void QNetEasyMusicSlider::setStartValue(float value)
{
	x_fMinValue = value;

	update();
}

float QNetEasyMusicSlider::startValue() const
{
	return x_fMaxValue;

}

void QNetEasyMusicSlider::setEndValue(float value)
{
	x_fMaxValue = value;

	update();
}

float QNetEasyMusicSlider::endValue() const
{
	return x_fMaxValue;
}

void QNetEasyMusicSlider::setCurrentPos(float value)
{
	x_fValue = value;

	update();
}

void QNetEasyMusicSlider::paintEvent(QPaintEvent *event)
{
	QPainter painter(this);

	painter.setRenderHint(QPainter::Antialiasing);

	drawLine(&painter);

	drawBlock(&painter);

	initBackgroundColor();

	QWidget::paintEvent(event);
}

void QNetEasyMusicSlider::mousePressEvent(QMouseEvent *event)
{
	if (event->button() == Qt::LeftButton)
	{
		QPoint _pos = event->pos();

		if (_pos.x() < x_rectLine.left() || _pos.x() > x_rectLine.right())
		{
			return;
		}

		if (x_rectBlock.contains(event->pos()))
		{
			x_pressedPos = event->pos();

			x_bLBPressed = true;
		}
		else
		{
			int _x = event->pos().x();

			int _overWidth = _x - x_rectLine.x();

			x_fValue = ((float)_overWidth / (float)x_rectLine.width()) * (x_fMaxValue - x_fMinValue) + x_fMinValue;

			update();
		}
	}
}

void QNetEasyMusicSlider::mouseReleaseEvent(QMouseEvent *event)
{
	Q_UNUSED(event);

	x_bLBPressed = false;
}

void QNetEasyMusicSlider::mouseMoveEvent(QMouseEvent *event)
{
	QPoint _pos = event->pos();

	if (_pos.x() < x_rectLine.left() || _pos.x() > x_rectLine.right())
	{
		return;
	}

	if (x_bLBPressed)
	{
		int _x = event->pos().x();

		int _overWidth = _x - x_rectLine.x();

		x_fValue = ((float)_overWidth / (float)x_rectLine.width()) * (x_fMaxValue - x_fMinValue) + x_fMinValue;
	}
	else
	{
		if (x_rectBlock.contains(event->pos()))
		{
			QPoint _pos = mapToGlobal(event->pos());
			QToolTip::showText(_pos, QString("%1").arg(x_fValue), this);
			setCursor(Qt::PointingHandCursor);
			x_bBlackShadow = true;
		}
		else
		{
			QToolTip::hideText();
			setCursor(Qt::ArrowCursor);
			x_bBlackShadow = false;
		}
	}

	update();
}

void QNetEasyMusicSlider::drawBg(QPainter* painter)
{

}

void QNetEasyMusicSlider::drawLine(QPainter* painter)
{
	QRect _rect = this->rect();

	x_rectLine = QRect(_rect.x() + x_nBlockWidth / 2, _rect.center().y() - x_nLineHeight / 2, _rect.width() - x_nBlockWidth, x_nLineHeight);

	float x_fScale = (x_fValue - x_fMinValue) / (x_fMaxValue - x_fMinValue);

	emit valueChanged(x_fValue);

	float _overWidth = x_rectLine.width() * x_fScale;

	x_rectLeftLine = QRect(x_rectLine.x(), x_rectLine.y(), _overWidth, x_nLineHeight);
	x_rectRightLine = QRect(x_rectLeftLine.right(), x_rectLine.y(), x_rectLine.width() - _overWidth, x_nLineHeight);

	painter->save();
	QBrush _brushOver(x_lineOverColor);
	painter->setBrush(_brushOver);
	painter->setPen(Qt::NoPen);
	painter->drawRoundedRect(x_rectLeftLine, 2, 2);
	painter->restore();

	painter->save();
	QBrush _brush(x_lineColor);
	painter->setBrush(_brush);
	painter->setPen(Qt::NoPen);
	painter->drawRoundedRect(x_rectRightLine, 2, 2);
	painter->restore();
}

void QNetEasyMusicSlider::drawBlock(QPainter* painter)
{
	//画外圆
	{
		painter->save();
		QBrush brush(x_blackBgColor);
		painter->setBrush(brush);
		QPen _pen(x_blackBorderColor);
		painter->setPen(_pen);
		x_rectBlock = QRect(x_rectLeftLine.right() - x_nBlockWidth / 2 + x_shdaowBorder, x_rectLeftLine.center().y() - x_nBlockWidth / 2 + x_shdaowBorder, x_nBlockWidth - 2 * x_shdaowBorder, x_nBlockWidth - 2 * x_shdaowBorder);
		painter->drawEllipse(x_rectBlock);
		painter->restore();
	}

	//画中心点
	{
		painter->save();
		QBrush brush(x_blackCenterColor);
		painter->setBrush(brush);
		painter->setPen(Qt::NoPen);
		QRect _rectEllipse = QRect(x_rectLeftLine.right() - 2, x_rectLeftLine.center().y() - 2, 4, 4);
		painter->drawEllipse(_rectEllipse);
		painter->restore();
	}

	//画阴影
	if (x_bBlackShadow)
	{
		painter->save();
		QColor color(0, 0, 0, 90);
		for (int i = 0; i < x_shdaowBorder; ++i)
		{
			QPainterPath path;
			path.setFillRule(Qt::WindingFill);
			path.addEllipse(x_rectBlock.x() - i, x_rectBlock.y() - i, x_rectBlock.width() + 2 * i, x_rectBlock.height() + 2 * i);
			
			color.setAlpha(90 - qSqrt(i) * 50);
			painter->setPen(color);
			painter->drawPath(path);
		}
		painter->restore();
	}
}

void QNetEasyMusicSlider::initBackgroundColor()
{
	QStyleOption opt;
	opt.init(this);

	QPainter painter(this);
	style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
}


使用

QNetEasyMusicSlider* x_pSlider = new QNetEasyMusicSlider(this);

x_pSlider->setCurrentPos(20);
x_pSlider->setFixedWidth(200);
connect(x_pSlider, SIGNAL(valueChanged(float)), this, SLOT(slot_valueChanged(float)));

说明

QNetEasyMusicSlider类中参数都已添加注释,知己根据需要可以添加代码来操作这些参数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值