语音播放脉冲运行效果:
代码:
#ifndef MYVOICEQUOTELOADINGWIDGET_H
#define MYVOICEQUOTELOADINGWIDGET_H
#include <QWidget>
// 语音播放动态icon
// 1、icon尺寸:
// 16*16
// 2、柱子尺寸:
// h最长=12,最短=3;
// w=2;
// 间距=3;
// 3、颜色:FFFFFF
// 4、圆角:1
// 从左到右依次阶梯变短
class QPropertyAnimation;
class MyVoiceQuoteLoadingWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY(int status READ status WRITE setStatus)
public:
explicit MyVoiceQuoteLoadingWidget(QWidget* parent = nullptr);
~MyVoiceQuoteLoadingWidget(){}
void start();
void stop();
public:
int status() const;
void setStatus(int newStatus);
protected:
void paintEvent(QPaintEvent *event) override;
private:
int mStatus { -100000 };
QPropertyAnimation *mAnimation {nullptr};
void init();
};
#endif // MYVOICEQUOTELOADINGWIDGET_H
#include "myvoicequoteloadingwidget.h"
#include <QPropertyAnimation>
#define MIN_VALUE 0
#define MAX_VALUE 3000
#define BASE_VALUE 1000
MyVoiceQuoteLoadingWidget::MyVoiceQuoteLoadingWidget(QWidget* parent) : QWidget { parent }
{
init();
}
void MyVoiceQuoteLoadingWidget::start()
{
if (mAnimation->state() != QAbstractAnimation::Running) {
mAnimation->start();
}
}
void MyVoiceQuoteLoadingWidget::stop()
{
mAnimation->stop();
setStatus(-2*MAX_VALUE);
}
void MyVoiceQuoteLoadingWidget::init()
{
setFixedSize(16, 16);
mAnimation = new QPropertyAnimation(this, "status", this);
mAnimation->setDuration(800);
mAnimation->setStartValue(-MAX_VALUE);
mAnimation->setEndValue(MAX_VALUE);
mAnimation->setLoopCount(-1);
}
int MyVoiceQuoteLoadingWidget::status() const
{
return mStatus;
}
void MyVoiceQuoteLoadingWidget::setStatus(int newStatus)
{
if (newStatus == mStatus) return;
mStatus = newStatus;
update();
}
// 播放动态icon
// 1、icon尺寸:
// 16*16
// 2、柱子尺寸:
// h最长=12,最短=3;
// w=2;
// 间距=3;
// 3、颜色:FFFFFF
// 4、圆角:1
// 从左到右依次阶梯变短
void MyVoiceQuoteLoadingWidget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
//const qreal spacing = 3;
if (height() < 12 || width() < 12) {
return;
}
const qreal barW = 2;
const qreal maxBarHeight = 12;
const qreal midBarHeight = 7.5;
const qreal minBarHeight = 3;
const qreal padding = 2.0;
qreal h = height();
qreal w = width();
qreal x0 = padding;
qreal x1 = w/2.0 - 0.5;
qreal x2 = w - padding - barW/2.0;
QColor cor = Qt::white;
QPainter p(this);
p.setRenderHints(QPainter::Antialiasing);
p.setPen(QPen(cor, barW, Qt::SolidLine, Qt::RoundCap));
p.setBrush(Qt::NoBrush);
qreal factor = 1.0 - (mStatus % BASE_VALUE) / qreal(BASE_VALUE);
if (mStatus >= 0) {
factor = 1.0 - (mStatus % BASE_VALUE) / qreal(BASE_VALUE);
} else {
factor = 1.0 - (qAbs(mStatus) % BASE_VALUE) / qreal(BASE_VALUE);
}
qreal barH = 0;
qreal vOffset = 0;
int status = qAbs(mStatus);
if (BASE_VALUE*2 < status && status <= MAX_VALUE) {
// 第一根柱子
barH = midBarHeight - (maxBarHeight - minBarHeight)*factor;
vOffset = (h - barH)/2.0;
p.drawLine(QPointF(x0, vOffset), QPointF(x0, vOffset + barH));
// 第二根柱子
barH = midBarHeight + (maxBarHeight - midBarHeight)*factor;
vOffset = (h - barH)/2.0;
p.drawLine(QPointF(x1, vOffset), QPointF(x1, vOffset + barH));
// 第三根柱子
barH = minBarHeight;
vOffset = (h - barH)/2.0;
p.drawLine(QPointF(x2, vOffset), QPointF(x2, vOffset + barH));
} else if (BASE_VALUE < status && status <= BASE_VALUE*2) {
// 第二根柱子
barH = maxBarHeight - (maxBarHeight - minBarHeight)*factor;
vOffset = (h - barH)/2.0;
p.drawLine(QPointF(x1, vOffset), QPointF(x1, vOffset + barH));
// 第三根柱子
barH = midBarHeight + (maxBarHeight - midBarHeight)*factor;
vOffset = (h - barH)/2.0;
p.drawLine(QPointF(x2, vOffset), QPointF(x2, vOffset + barH));
// 第一根柱子
barH = minBarHeight;
vOffset = (h - barH)/2.0;
p.drawLine(QPointF(x0, vOffset), QPointF(x0, vOffset + barH));
} else if (MIN_VALUE <= status && status <= BASE_VALUE) {
// 第三根柱子
barH = maxBarHeight - (maxBarHeight - minBarHeight)*factor;
vOffset = (h - barH)/2.0;
p.drawLine(QPointF(x2, vOffset), QPointF(x2, vOffset + barH));
// 第一根柱子
barH = midBarHeight + (maxBarHeight - midBarHeight)*factor;
vOffset = (h - barH)/2.0;
p.drawLine(QPointF(x0, vOffset), QPointF(x0, vOffset + barH));
// 第二根柱子
barH = minBarHeight;
vOffset = (h - barH)/2.0;
p.drawLine(QPointF(x1, vOffset), QPointF(x1, vOffset + barH));
} else {
p.drawLine(QPointF(x0, (h - midBarHeight)/2.0), QPointF(x0, (h - midBarHeight)/2.0 + midBarHeight));
p.drawLine(QPointF(x1, (h - maxBarHeight)/2.0), QPointF(x1, (h - maxBarHeight)/2.0 + maxBarHeight));
p.drawLine(QPointF(x2, (h - midBarHeight)/2.0), QPointF(x2, (h - midBarHeight)/2.0 + midBarHeight));
}
}