效果图如下:
实现思想:
上半部分: 中间显示声音图片, 然后围着声音图片画一圈线条
下半部分: 修改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;
}