提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
使用qt显示双通道栅格音频根据左右声道不同音量大小显示不同颜色,音量由低到高分别为绿色,黄色,红色
一、利用Qpainter显示单个小栅格,并设置颜色
代码如下:
class VolumeBarItem : public QGraphicsItem {
public:
VolumeBarItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = nullptr)
: QGraphicsItem(parent), xPos(x), yPos(y), itemWidth(width), itemHeight(height), m_color(QColor(207, 207, 207, 200)) {}
int num{0};
QRectF boundingRect() const override {
return QRectF(xPos, yPos, itemWidth, itemHeight);
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override {
Q_UNUSED(option)
Q_UNUSED(widget)
// painter=new QPainter();
painter->setPen(Qt::NoPen);
painter->setBrush(400 > 0 ? m_color: QColor(207, 207, 207, 200)); // 根据音量级别设置颜色
painter->drawRect(QRectF(xPos, yPos, 150 * itemWidth / 100.0, itemHeight));
}
void setVolumeLevel(QColor ncolor) {
m_color = ncolor;
update();
}
private:
qreal xPos, yPos;
qreal itemWidth, itemHeight;
QColor m_color; // 音量级别,0-100
};
二、添加场景设置音量条,设置每个栅格长宽并根据左右声道设置栅格位置
代码如下:
void Audio::initui( QGraphicsScene *scene){
VolumeBarItem *volumeBarItem;
QGraphicsView *view;
ui->widget->setWindowFlag(Qt::FramelessWindowHint);
ui->widget->setStyleSheet("background-color: transparent;");
QVBoxLayout *layout = new QVBoxLayout(ui->widget);
layout->setSpacing(0);
layout->setMargin(0);
// 创建QGraphicsView
view = new QGraphicsView(scene);
view->setMaximumWidth(28);
view->setMinimumWidth(28);
view->setRenderHint(QPainter::Antialiasing);
//view->setBackgroundBrush(Qt::transparent); // 设置视图背景为白色
view->setWindowFlags(Qt::FramelessWindowHint);
view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// 设置视图背景透明
//# 设置透明度为0(完全透明)
view->setWindowOpacity(0);
view->setStyleSheet("border: none;QGraphicsView { background-color: transparent; }");
layout->addWidget(view);
// return;
// 设置场景大小
//scene->setSceneRect(0, 0, 50, 300); // 假设宽度为300,高度为50
const int numBars = 75; // 格子数量
const int barWidth = 5; // 每个格子的宽度
const int barHeight = 3; // 格子的高度
const int spacing = 2; // 格子之间的间距
qreal yPos = 300;
for (int i = 0; i < numBars*2; ++i) {
qreal xPos=0;
if(i%2==1){
xPos=150 * barWidth / 100.0+3;
}
if(i%2==0){
yPos -= (barHeight + spacing); // 更新下一个格子的位置
}
VolumeBarItem *barItem = new VolumeBarItem(xPos,yPos, barWidth, barHeight);
barItem->num=i;
barItem->setVolumeLevel(QColor(207, 207, 207, 200));
scene->addItem(barItem);
}
}
三、根据音量大小实时改变栅格颜色
代码如下:
#define MIN_VALUE 1e-8
#define IS_DOUBLE_ZERO(d) (abs(d) < MIN_VALUE)
#define RED_YELLOW_LINE 61.0 //-11
#define YELLOW_GREEN_LINE 50.0 //-20
#define SOUND_COLUMN_HIEGHT 70.0
#define SOUND_COLUMN_THRESHOLD 72.0
void Audio::setVolume(int audionum, int levelL, int levelR,QGraphicsScene *scene) {
QColor colorL,colorR;
int No=0;
int addnum=0;
double ratio=1;
double maxL=(levelL+SOUND_COLUMN_THRESHOLD)*ratio;
double maxR=(levelR+SOUND_COLUMN_THRESHOLD)*ratio;
QList<QGraphicsItem *> items = scene->items();
for (QGraphicsItem *item : items) {
if (dynamic_cast<VolumeBarItem *>(item)) {
if(static_cast<VolumeBarItem *>(item)->num%2==0){
No=(int)floor(static_cast<VolumeBarItem *>(item)->num/2);
if(No>addnum){
colorL=GetColorA(No-addnum,ratio, maxL);
static_cast<VolumeBarItem *>(item)->setVolumeLevel(colorL);
}
}else{
No=(int)floor(static_cast<VolumeBarItem *>(item)->num/2);
if(No>addnum){
colorR=GetColorA(No-addnum,ratio, maxR);
static_cast<VolumeBarItem *>(item)->setVolumeLevel(colorR);
}
}
}
}
scene->update();
}
QColor GetColorA(int w,double num, double max){
QColor color;
color=QColor(207, 207, 207, 200);
if (!IS_DOUBLE_ZERO(max))
{
if(0<=w&&w<=num*YELLOW_GREEN_LINE&&w<=max){
color=QColor(0, 255, 0);
}else if(YELLOW_GREEN_LINE*num<w&&RED_YELLOW_LINE*num>=w&&w<=max){
color=QColor(222, 255, 0);
}else if(RED_YELLOW_LINE*num<w&&SOUND_COLUMN_HIEGHT*num>=w&&w<=max){
color=QColor(255, 0, 0);
}
else{
color=QColor(207, 207, 207, 200);
}
}
else{
color=QColor(207, 207, 207, 200);
}
return color;
}
四、调用
代码如下:
QGraphicsScene *scene;
m_audio_Show=new Audio(this);
m_audio_Show->initui(scene);
输入当前左右声道音量大小(aL,aR)和音量条长度(audionum),实时改变栅格颜色
m_audio_Show->setVolume(audionum,aL,aR,scene);