QT自定义UI组件_腾讯视屏声音控件
效果图如下:

实现思想:
上半部分: 中间显示声音图片, 然后围着声音图片画一圈线条
下半部分: 修改QProcessBar的样式
代码如下:
#include <QWidget>
#include <QLabel>
#include <QVBoxLayout>
#include <QSlider>
#include <QProgressBar>
class SoundModule : public QWidget
{
Q_OBJECT
public:
explicit SoundModule(QWidget *parent = nullptr);
void paintEvent(QPaintEvent *event);
void initWidget();
private:
QLabel* m_SoundLab;
QProgressBar* m_ProBar;
QSlider* m_SoundSlider;
QVBoxLayout* m_MainLayout;
int m_MaxValue;
int m_Value;
signals:
public slots:
void onValueChanged(int);
};
cpp文件
#include "soundmodule.h"
#include <QTextCodec>
#include <QPainter>
#include <QPixmap>
#include <QPalette>
#include <QDebug>
#include <QFont>
#include <QMouseEvent>
SoundModule::SoundModule(QWidget *parent) : QWidget(parent), m_MaxValue(32), m_Value(0)
{
this->setFixedSize(QSize(600, 360));
initWidget();
connect(m_SoundSlider, &QSlider::valueChanged, this, &SoundModule::onValueChanged);
}
void SoundModule::initWidget()
{
QPalette pal = this->palette();
pal.setColor(QPalette::Background, Qt::transparent);
this->setPalette(pal);
m_MainLayout = new QVBoxLayout;
m_SoundLab = new QLabel;
m_SoundSlider = new QSlider;
m_SoundSlider->setOrientation(Qt::Horizontal);
m_SoundSlider->setMinimum(0);
m_SoundSlider->setMaximum(m_MaxValue);
m_SoundSlider->setFixedSize(300, 20);
m_SoundLab->setFixedSize(50,50);
QPixmap soundPix = QPixmap(":/png/soundCls.png");
soundPix=soundPix.scaled(m_SoundLab->width(), m_SoundLab->height());
m_SoundLab->setPixmap(soundPix);
m_ProBar = new QProgressBar;
m_ProBar->setObjectName("voicebar");
m_ProBar->setFixedWidth(300);
m_ProBar->setRange(0, m_MaxValue);
m_ProBar->setTextVisible(false);
m_MainLayout->addStretch(1);
m_MainLayout->addSpacing(5);
m_MainLayout->addWidget(m_SoundLab, 0, Qt::AlignCenter);
m_MainLayout->addSpacing(40);
m_MainLayout->addWidget(m_ProBar, 0, Qt::AlignCenter);
m_MainLayout->addSpacing(25);
m_MainLayout->addWidget(m_SoundSlider, 0, Qt::AlignCenter);
m_MainLayout->addSpacing(5);
m_MainLayout->addStretch(1);
this->setLayout(m_MainLayout);
}
void SoundModule::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter paint(this);
paint.setRenderHint(QPainter::Antialiasing);
QPen penSytle;
penSytle.setColor(Qt::white);
penSytle.setWidthF(5);
penSytle.setCapStyle(Qt::MPenCapStyle);
paint.setPen(penSytle);
//获取声音图片在窗口的位置
QPoint soudLab = m_SoundLab->mapToParent(m_SoundLab->pos());
//计算声音图片中心位置
QPoint center((soudLab.x() + m_SoundLab->width()) / 2, (m_SoundLab->height() + soudLab.y()) / 2);
//将坐标原点平移到声音图片的中心
paint.translate(center);
int radius = -40; // 正数: 正下方, 负数: 正上方
double rotate = 360.0 / m_MaxValue;
//绘制图片
for(int i = 0; i < m_Value; i++)
{
paint.drawLine( 0 , radius, 0, radius * 1.4);
if((i % 2 == 1))
{
paint.setOpacity(0.5);
paint.rotate(rotate * 2);
}
else
{
paint.setOpacity(1.0);
}
}
}
void SoundModule::onValueChanged(int value)
{
m_Value = value;
m_ProBar->setValue(m_Value);
QString pngPath = m_Value == 0 ? QString(":/png/soundCls.png") : QString(":/png/sound.png");
QPixmap soundPix = QPixmap(pngPath);
soundPix=soundPix.scaled(m_SoundLab->width(), m_SoundLab->height());
m_SoundLab->setPixmap(soundPix);
update();
}
translate函数: 坐标原点平移
rotate函数: 沿着原点坐标旋转的角度, radius = 360 / 16 , 360: 一圈的弧度, 16: 一圈总共显示16条线
QProcessBar在qss文件显示
QProgressBar#voicebar
{
border: 0px solid grey; //线条显示以宽度设置
border-radius: 5px; //弧度
background-color: #FFFFFF; //背景颜色
text-align: center; //显示进度条值的text位置, left center rigth
color: #8B0000; //进度条值的颜色
}
QProgressBar#voicebar:chunk //进度条值的颜色, 以弧度设置
{
background-color: qlineargradient(spread:repeat,x1:0,y1:0,x2:1,y2:0,stop:0 #00CED1, stop:0.5 #FFF990 ,stop:1 #FF5E79);
border-radius: 5px;
}

浙公网安备 33010602011771号