模仿网易云音乐播放进度条
通过重载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类中参数都已添加注释,知己根据需要可以添加代码来操作这些参数