仿照b站音量调节效果

b站效果:

Qt仿制效果图:

实现步骤:

1、绘制背景、绘制矩形、填充颜色

2、难点在于鼠标悬浮所在的矩形需要调整绘制区域,重点看for循环;

1、头文件

#pragma once
#include 

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 
#include 
#include 
#include 
#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();
}

 

你可能感兴趣的:(Qt)