Qt——功能:使用QSlider实现音量条

测试环境:win10、Qt Creator 4.11.1、5.14.2版本SDK

github:https://github.com/coldfirehello/QtDemo.git

 

音量需求:

 

注意事项:

1.音量移动到0或100时,不能有剩余部分

 

解决办法:剩余部分设置为背景色

 

上代码:

volume.h
#ifndef VOLUME_H
#define VOLUME_H

#include <QWidget>
#include <QSlider>

class Volume : public QWidget
{
    Q_OBJECT
public:
    explicit Volume(QWidget *parent = nullptr);
    ~Volume();

    void setValue(int value);

signals:
    void signalVolumeChanged(int volume);

private:
    void initUI();
    void onVolumeChanged();

protected:
    void paintEvent(QPaintEvent *event) override;
    bool event(QEvent *e) override;

private:
    QSlider* m_slider;
};

#endif // VOLUME_H

volume.cpp
#include "volume.h"
#include <QApplication>
#include <QEvent>
#include <QPainter>
#include <QStyleOption>
#include <QVBoxLayout>

Volume::Volume(QWidget *parent) : QWidget(parent),
    m_slider(nullptr)
{
    setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint);
    setAttribute(Qt::WA_TranslucentBackground, true);

    initUI();
}

Volume::~Volume()
{

}

void Volume::setValue(int value)
{
    if(m_slider != nullptr)
    {
        m_slider->setValue(value);
    }
}

void Volume::initUI()
{
    QWidget* backgroundWidget = new QWidget(this);
    backgroundWidget->resize(36, 153);
    backgroundWidget->setStyleSheet("QWidget{background-color:rgba(0, 0, 0, 0.8);border-radius:18px;}");

    m_slider = new QSlider();
    m_slider->resize(36, 121);
    m_slider->setMaximum(100);
    m_slider->setMinimum(0);
    m_slider->setValue(0);
    m_slider->setStyleSheet("QSlider{background:transparent;}"
                            "QSlider::add-page:vertical{background-color:#FFFFFF;width:4px;border-radius:2px;}"
                            "QSlider::sub-page:vertical{background-color:rgba(196, 196, 196, 0.5);width:4px;border-radius:2px;}"
                            "QSlider::groove:vertical{background:transparent;width:4px;border-radius:2px;}"
                            "QSlider::handle:vertical{height:20px;width:20px;border-image:url(:/images/handle.png);margin-top:0px;margin-bottom:0px;margin-left:-8px;margin-right:-8px;}"
                            "QSlider::handle:vertical:hover{height:20px;width:20px;border-image:url(:/images/plus.png);margin-top:0px;margin-bottom:0px;margin-left:-8px;margin-right:-8px;}"
                            "QSlider::handle:vertical:pressed{height:20px;width:20px;border-image:url(:/images/plus.png);margin-top:0px;margin-bottom:0px;margin-left:-8px;margin-right:-8px;}");

    connect(m_slider, &QSlider::valueChanged, this, &Volume::onVolumeChanged);

    QVBoxLayout* vLayout = new QVBoxLayout();
    vLayout->setContentsMargins(0, 16, 0, 16);
    vLayout->setAlignment(Qt::AlignCenter);
    vLayout->setSpacing(0);
    vLayout->addWidget(m_slider);

    backgroundWidget->setLayout(vLayout);

    setValue(10);
}

void Volume::onVolumeChanged()
{
    if(m_slider != nullptr)
    {
        int value = m_slider->value();

        if (value == 0)
        {
            m_slider->setStyleSheet("QSlider{background:transparent;}"
                                    "QSlider::add-page:vertical{background-color:rgba(0, 0, 0, 0.8);width:4px;border-radius:2px;}"
                                    "QSlider::sub-page:vertical{background-color:rgba(196, 196, 196, 0.5);width:4px;border-radius:2px;}"
                                    "QSlider::groove:vertical{background:transparent;width:4px;border-radius:2px;}"
                                    "QSlider::handle:vertical{height:20px;width:21px;border-image:url(:/images/handle.png);margin-top:0px;margin-bottom:0px;margin-left:-8px;margin-right:-8px;}"
                                    "QSlider::handle:vertical:hover{height:20px;width:21px;border-image:url(:/images/plus.png);margin-top:0px;margin-bottom:0px;margin-left:-8px;margin-right:-8px;}"
                                    "QSlider::handle:vertical:pressed{height:20px;width:21px;border-image:url(:/images/plus.png);margin-top:0px;margin-bottom:0px;margin-left:-8px;margin-right:-8px;}");
        }
        else if (value > 0 && value < 100)
        {
            m_slider->setStyleSheet("QSlider{background:transparent;}"
                                    "QSlider::add-page:vertical{background-color:#FFFFFF;width:4px;border-radius:2px;}"
                                    "QSlider::sub-page:vertical{background-color:rgba(196, 196, 196, 0.5);width:4px;border-radius:2px;}"
                                    "QSlider::groove:vertical{background:transparent;width:4px;border-radius:2px;}"
                                    "QSlider::handle:vertical{height:20px;width:21px;border-image:url(:/images/handle.png);margin-top:0px;margin-bottom:0px;margin-left:-8px;margin-right:-8px;}"
                                    "QSlider::handle:vertical:hover{height:20px;width:21px;border-image:url(:/images/plus.png);margin-top:0px;margin-bottom:0px;margin-left:-8px;margin-right:-8px;}"
                                    "QSlider::handle:vertical:pressed{height:20px;width:21px;border-image:url(:/images/plus.png);margin-top:0px;margin-bottom:0px;margin-left:-8px;margin-right:-8px;}");
        }
        else
        {
            m_slider->setStyleSheet("QSlider{background:transparent;}"
                                    "QSlider::add-page:vertical{background-color:#FFFFFF;width:4px;border-radius:2px;}"
                                    "QSlider::sub-page:vertical{background-color:rgba(0, 0, 0, 0.8);width:4px;border-radius:2px;}"
                                    "QSlider::groove:vertical{background:transparent;width:4px;border-radius:2px;}"
                                    "QSlider::handle:vertical{height:20px;width:21px;border-image:url(:/images/handle.png);margin-top:0px;margin-bottom:0px;margin-left:-8px;margin-right:-8px;}"
                                    "QSlider::handle:vertical:hover{height:20px;width:21px;border-image:url(:/images/plus.png);margin-top:0px;margin-bottom:0px;margin-left:-8px;margin-right:-8px;}"
                                    "QSlider::handle:vertical:pressed{height:20px;width:21px;border-image:url(:/images/plus.png);margin-top:0px;margin-bottom:0px;margin-left:-8px;margin-right:-8px;}");
        }

        emit signalVolumeChanged(value);
    }
}

void Volume::paintEvent(QPaintEvent *event)
{
    QStyleOption option;

    option.init(this);

    QPainter p(this);

    style()->drawPrimitive(QStyle::PE_Widget, &option, &p, this);
}

bool Volume::event(QEvent *e)
{
    if (e->type() == QEvent::ActivationChange)
    {
        if (QApplication::activeWindow() != this)
        {
            this->close();
        }
    }

    return QWidget::event(e);
}

测试代码:

#include "volume.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Volume w;
    w.show();
    return a.exec();
}

 

注意:

因为使用了border-image这种样式,因此groove宽度+扩展宽度最好不小于图片宽度,否则会宽度会缩放。如果使用background-image样式,可能显示位置不对。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值