Qt/C++ 波形绘制双缓冲下改善PaintEvent连续绘制卡顿问题(完整代码解析)

devtools/2024/9/22 23:00:26/

  1. 音频波形可视化:该控件用于将音频样本数据可视化为波形,常用于音频处理软件中以展示音频信号的时间域特性。

  2. 动态数据绘制:控件能够响应外部数据的变化并重新绘制波形,适用于实时或动态的音频数据流。

  3. 自定义绘制逻辑:通过Qt的绘图API,特别是QPainterQPainterPath,实现了波形的自定义绘制,包括线条的平滑、颜色渐变以及路径的描绘。

  4. 性能优化:通过双缓冲技术(使用QPixmap)和适当的数据处理,减少了绘制过程中的计算量,提高了渲染效率。

  5. 颜色编码:使用颜色渐变来区分波形的不同振幅区域,比如使用红色到蓝色的渐变表示波形的高低振幅,绿色表示零点线,使得波形的阅读更直观。

  6. 可扩展性:控件为Qt框架下的自定义控件,可以很容易地集成到更大的Qt应用程序中,并根据需求进行定制和扩展。

    
    #ifndef WAVEFORMWIDGET_H
    #define WAVEFORMWIDGET_H#include <QWidget>
    #include <QPixmap>class WaveformWidget : public QWidget {Q_OBJECTpublic:explicit WaveformWidget(QWidget *parent = nullptr);~WaveformWidget();void setSamples(const QList<float> &newSamples);protected:void paintEvent(QPaintEvent *event) override;void resizeEvent(QResizeEvent *event) override;private:QList<float> samples; // 用于存储音频样本的列表QPixmap buffer; // 双缓冲的画布void redrawBuffer(); // 在画布上重新绘制波形
    };#endif // WAVEFORMWIDGET_H
    #include "WaveformWidget.h"
    #include <QPainter>
    #include <QResizeEvent>WaveformWidget::WaveformWidget(QWidget *parent): QWidget(parent) {// 初始化双缓冲画布buffer = QPixmap(size());buffer.fill(Qt::black);
    }WaveformWidget::~WaveformWidget() {
    }void WaveformWidget::setSamples(const QList<float> &newSamples) {samples = newSamples;redrawBuffer(); // 更新画布
    }void WaveformWidget::paintEvent(QPaintEvent *event) {QPainter painter(this);painter.drawPixmap(0, 0, buffer);
    }void WaveformWidget::resizeEvent(QResizeEvent *event) {// 调整画布大小并重新绘制buffer = QPixmap(event->size());buffer.fill(Qt::black);redrawBuffer();
    }void WaveformWidget::redrawBuffer() {// 确保画布准备好if (buffer.size() != size()) {buffer = QPixmap(size());}QPainter painter(&buffer);painter.setRenderHint(QPainter::Antialiasing);// 重置画布背景buffer.fill(Qt::black);if (samples.isEmpty()) return;const int middleY = buffer.height() / 2;const int upperLimit = middleY / 2;  // -50 to 50 对应的 Y 坐标const int lowerLimit = middleY + upperLimit;// 创建路径和描边路径QPainterPath path, strokePath;path.moveTo(0, middleY);qreal xStep = static_cast<qreal>(buffer.width()) / (samples.size() - 1);// 根据样本数据构造波形路径for (int i = 0; i < samples.size(); ++i) {qreal x = i * xStep;qreal y = middleY - (samples.at(i) * middleY / 100.0);path.lineTo(x, y);strokePath.lineTo(x, y);}// 绘制渐变QLinearGradient gradient(0, 0, 0, buffer.height());gradient.setColorAt(0.0, QColor(255, 0, 0));    // 顶部为红色gradient.setColorAt(0.25, QColor(0, 0, 255));   // 中部为蓝色gradient.setColorAt(0.5, Qt::transparent);      // 中间透明gradient.setColorAt(0.75, QColor(0, 0, 255));   // 中部为蓝色gradient.setColorAt(1.0, QColor(255, 0, 0));    // 底部为红色QPen pen(gradient, 2);painter.setPen(pen);painter.drawPath(strokePath);// 绘制中间的零点线QPen centerLinePen(Qt::green);centerLinePen.setWidth(1);painter.setPen(centerLinePen);painter.drawLine(0, middleY, buffer.width(), middleY);// 请求更新控件update();
    }


http://www.ppmy.cn/devtools/25337.html

相关文章

大数据时代的引擎:大数据架构随记

大数据架构通常可以分为以下几层&#xff1a; 一、数据采集层 负责从各种数据源采集、清洗、转换、丰富以及格式化数据&#xff0c;可能包括结构化、半结构化和非结构化的数据。 1.1、常用的技术 在大数据领域&#xff0c;数据采集是一个关键的环节&#xff0c;常用的数据采集…

Unity 递归实现数字不重复的排列组合

实现 private void Permutation(List<int> num, int leftIndex, List<string> strs) {if (leftIndex < num.Count){for (int rightIndex leftIndex; rightIndex < num.Count; rightIndex){Swap(num, leftIndex, rightIndex);Permutation(num, leftIndex 1…

Leetcode_相交链表

✨✨所属专栏&#xff1a;LeetCode刷题专栏✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 题目&#xff1a; 题解&#xff1a; 看到这个题目首先我们要排除链表逆置的想法&#xff0c;如图、因为c1节点只有一个next指针&#xff0c;逆置后不可能同时指向a2和b3节点。 其次有的的同学…

(iFlyCode、FREEGPT、Copilot、AIPlus、稳定高效)分享好用的ChatGPT

目录 1、iFlyCode 2、FREEGPT 3、Microsoft Copilot: 你的日常 AI 助手 4、AIPlus

web server apache tomcat11-24-Virtual Hosting and Tomcat

前言 整理这个官方翻译的系列&#xff0c;原因是网上大部分的 tomcat 版本比较旧&#xff0c;此版本为 v11 最新的版本。 开源项目 从零手写实现 tomcat minicat 别称【嗅虎】心有猛虎&#xff0c;轻嗅蔷薇。 系列文章 web server apache tomcat11-01-官方文档入门介绍 web…

GaussDB轻量化运维管理工具介绍

前言 本期课程将从管理平台的架构出发&#xff0c;结合平台的实例管理、实例升级、容灾管理和监控告警的功能和操作介绍&#xff0c;全面覆盖日常运维操作&#xff0c;带您理解并熟练运用GaussDB运维平台完成运维工作。 一、GaussDB 运维管理平台简介 开放生态层 友好Web界面…

怎么用电子章盖骑缝章?

使用电子章盖骑缝章通常涉及以下步骤&#xff0c;具体操作可能会因使用的电子签章软件或平台有所不同&#xff0c;但基本流程相似&#xff1a; 准备电子文档&#xff1a; 打开或上传需要加盖骑缝章的电子文档&#xff0c;通常支持PDF、Word等常见格式。 选择骑缝章功能&#xf…

webpack3升级webpack4遇到的各种问题汇总

webpack3升级webpack4遇到的各种问题汇总 问题1 var outputNamecompilation.mainTemplate.applyPluginWaterfull(asset-path,outputOptions.filename,{......)TypeError: compilation.mainTemplate.applyPluginsWaterfall is not a function解决方法 html-webpack-plugin 版…