b站效果:
Qt仿制效果图:
实现步骤:
1、绘制背景、绘制矩形、填充颜色
2、难点在于鼠标悬浮所在的矩形需要调整绘制区域,重点看for循环;
1、头文件
#pragma once
#include <QWidget>
class Value : public QWidget
{
Q_OBJECT
public:
Value(QWidget * parent = 0);
~Value();
void SetMaxValue(int Value);
void SetCurrentValue(int Value);
void SetValueNum(int count);
protected:
int m_maxValue;//最大值
int m_Value;//当前值
int m_mouseCurPos;//鼠标位置
int m_isPress;
int m_nValueNumber;//音量条数量
virtual void mousePressEvent(QMouseEvent *);
virtual void mouseMoveEvent(QMouseEvent *);
virtual void mouseReleaseEvent(QMouseEvent *);
virtual void leaveEvent(QEvent *);
virtual void paintEvent(QPaintEvent *);
signals:
void signal_valueChange(int value);
private:
};
2、实现文件
#include "value.h"
#include <QImage>
#include <QBitmap>
#include <QPainter>
#include <QMouseEvent>
#define RECT_Y_RATE 0.2
#define RECT_HEIGHT_RATE 0.8
Value::Value(QWidget * parent) : QWidget(parent),
m_maxValue(100),
m_Value(0),
m_isPress(false),
m_mouseCurPos(50),
m_nValueNumber(10)
{
setMouseTracking(true);
}
Value::~Value() = default;
void Value::SetMaxValue(int Value)
{
m_maxValue = Value;
}
void Value::SetCurrentValue(int Value)
{
m_Value = Value * width() / m_maxValue;
update();
}
void Value::SetValueNum(int count)
{
m_nValueNumber = count;
}
void Value::mousePressEvent(QMouseEvent *event)
{
m_isPress = true;
if(event->pos().x() >= 0 && event->pos().x() <= width()) {
m_mouseCurPos = event->pos().x();
m_Value = event->pos().x();
}
update();
}
void Value::mouseMoveEvent(QMouseEvent *event)
{
if(event->pos().x() >= 0 && event->pos().x() <= width()) {
m_mouseCurPos = event->pos().x();
if(m_isPress) {
m_Value = event->pos().x();
}
}
update();
}
void Value::mouseReleaseEvent(QMouseEvent *event)
{
if (m_isPress) {
m_isPress = false;
emit signal_valueChange(m_Value * m_maxValue / width());
}
}
void Value::leaveEvent(QEvent *event)
{
m_mouseCurPos = width();
update();
}
void Value::paintEvent(QPaintEvent *)
{
QPainter painter;
painter.setRenderHint(QPainter::Antialiasing);
painter.begin(this);
painter.fillRect(rect(), QColor(27, 28, 30, 0.8));
painter.end();
int nWidth = width(), nHeight = height();
QImage mask(nWidth, nHeight, QImage::Format_ARGB32);
painter.begin(&mask);
painter.setPen(Qt::NoPen);
painter.setBrush(QColor(0, 0, 0));
mask.fill(QColor(255, 255, 255, 0));
int scaleFlag = m_mouseCurPos * m_nValueNumber / nWidth;//计算鼠标所在的区域
for (int i = 0; i < m_nValueNumber; ++i) {
if (i == scaleFlag) {
painter.drawRect(
QRectF((nWidth / m_nValueNumber) * i + nWidth / (m_nValueNumber * 4)/*增加偏移*/,
0,
nWidth / (m_nValueNumber * 2),
nHeight * RECT_HEIGHT_RATE));
}
else {
painter.drawRect(
QRectF((nWidth / m_nValueNumber) * i + nWidth / (m_nValueNumber * 4),
nHeight * RECT_Y_RATE,
nWidth / (m_nValueNumber * 2),
nHeight * RECT_HEIGHT_RATE));
}
}
painter.end();
painter.begin(this);
painter.setRenderHint(QPainter::Antialiasing, true);
QRegion region(QBitmap::fromImage(mask));
painter.setClipRegion(region);
painter.fillRect(QRect(0, 0, nWidth, nHeight), QColor("#979797"));
painter.fillRect(QRect(0, 0, m_Value, nHeight), QColor("#3073F4"));
painter.end();
}