Qt to write custom controls 60 sound waveform chart

I. Introduction

This control comes from a music player, at the time of writing the music player, you need to convert audio data into corresponding spectrum display, the use of third-party library to handle fmod (fmod sound system is prepared for the game developers revolutionary audio engine, very powerful and fast hardware), responsible for fmod get audio data corresponding to the spectral sampling data, and then pass this control can be drawn, the controls need to focus on the main draw can be, so the corresponding package of classes focused fmod audio processing such as acquisition, provides isolation, more convenient to modify and increase the functionality, control the sound waveform diagram can be provided in addition to the sampling depth, it supports three display data pattern, line style, style cylindrical, smooth style. In order to be positioned to a position directly jump directly to the position of the audio, but also increased the number of bit line drawing lines.

Second, the realization of functions

  • 1: sampling depth can be set
  • 2: to set the current position of the line width / line color
  • 3: set the foreground / background color
  • 4: shows the data may be provided style, line style / lenticular pattern / smooth style

Third, renderings

Fourth, the header file code

#ifndef WAVEDATA_H
#define WAVEDATA_H

/**
 * 音量采样值波形控件 作者:feiyangqingyun(QQ:517216493) 2017-9-10
 * 1:可设置采样深度
 * 2:可设置当前位置线条宽度/线条颜色
 * 3:可设置前景色/背景色
 * 4:可设置数据展示样式,线条样式/柱状样式/平滑样式
 */

#include <QWidget>

#ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif

class QDESIGNER_WIDGET_EXPORT WaveData : public QWidget
#else
class WaveData : public QWidget
#endif

{
    Q_OBJECT
    Q_ENUMS(WaveStyle)
    Q_PROPERTY(double deep READ getDeep WRITE setDeep)
    Q_PROPERTY(bool showLine READ getShowLine WRITE setShowLine)
    Q_PROPERTY(int lineWidth READ getLineWidth WRITE setLineWidth)
    Q_PROPERTY(QColor lineColor READ getLineColor WRITE setLineColor)
    Q_PROPERTY(QColor foreground READ getForeground WRITE setForeground)
    Q_PROPERTY(QColor background READ getBackground WRITE setBackground)
    Q_PROPERTY(WaveStyle waveStyle READ getWaveStyle WRITE setWaveStyle)

public:
    enum WaveStyle {
        WaveStyle_Line = 0,     //线条样式
        WaveStyle_Smooth = 1,   //平滑样式
        WaveStyle_Bar = 2       //柱状样式
    };

    explicit WaveData(QWidget *parent = 0);

protected:
    void mousePressEvent(QMouseEvent *);
    void paintEvent(QPaintEvent *);
    void drawBg(QPainter *painter);
    void drawData(QPainter *painter);
    void drawLine(QPainter *painter);

private:    
    double deep;                //采集深度
    bool showLine;              //显示线条
    int lineWidth;              //线条宽度
    QColor lineColor;           //线条颜色
    QColor foreground;          //前景色
    QColor background;          //背景色
    WaveStyle waveStyle;        //数据样式

    int length;                 //采样点长度
    int position;               //当前位置
    QVector<float> data;        //采样点数据

public:    
    double getDeep()            const;
    bool getShowLine()          const;
    int getLineWidth()          const;
    QColor getLineColor()       const;
    QColor getForeground()      const;
    QColor getBackground()      const;
    WaveStyle getWaveStyle()    const;

    QSize sizeHint()            const;
    QSize minimumSizeHint()     const;

public slots:
    //设置深度
    void setDeep(double deep);

    //设置是否显示线条
    void setShowLine(bool showLine);
    //设置线条宽度
    void setLineWidth(int lineWidth);
    //设置线条颜色
    void setLineColor(const QColor &lineColor);

    //设置前景色
    void setForeground(const QColor &foreground);
    //设置背景色
    void setBackground(const QColor &background);

    //设置数据样式
    void setWaveStyle(const WaveStyle &waveStyle);

    //设置总长度
    void setLength(int length);
    //设置当前位置
    void setPosition(int position);

    //设置当前数据
    void setData(const QVector<float> &data);
    //清空数据
    void clearData();

signals:
    void positionChanged(int position);
};

#endif // WAVEDATA_H

Fifth, the core code

void WaveData::paintEvent(QPaintEvent *)
{
    //绘制准备工作,启用反锯齿
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing);

    //绘制背景
    drawBg(&painter);
    //绘制数据
    drawData(&painter);
    //绘制当前位置线条
    drawLine(&painter);
}

void WaveData::drawBg(QPainter *painter)
{
    painter->save();
    painter->fillRect(this->rect(), background);
    painter->restore();
}

void WaveData::drawData(QPainter *painter)
{
    if (data.count() == 0) {
        return;
    }

    painter->save();

    //获取最大值最小值
    float max = data.at(0);
    float min = data.at(0);
    int count = data.count();

    for (int i = 1; i < count; i++) {
        if (max < data.at(i)) {
            max = data.at(i);
        }

        if (min > data.at(i)) {
            min = data.at(i);
        }
    }

    //转化成当前屏幕的内的坐标大小
    max += deep;
    min -= deep;

    //自动转换数据到屏幕坐标位置
    QVector<QPointF> points;
    for (int i = 0; i < count; i++) {
        double x = i * width() / count;
        double y = height() - (((data.at(i) - min) / (max - min)) * height());
        points.append(QPointF(x, y));
    }

    //绘制不同的风格
    if (waveStyle == WaveStyle_Line) {
        painter->setPen(foreground);
        for (int i = 0; i < count - 1; i++) {
            painter->drawLine(points.at(i), points.at(i + 1));
        }
    } else if (waveStyle == WaveStyle_Smooth) {
        painter->setPen(foreground);
        QPainterPath path = SmoothCurveCreator::createSmoothCurve(points);
        painter->drawPath(path);
    } else if (waveStyle == WaveStyle_Bar) {
        double penWidth = width() / (count * 1.6);
        QPen pen;
        pen.setColor(foreground);
        pen.setWidthF(penWidth);
        pen.setCapStyle(Qt::RoundCap);
        painter->setPen(pen);

        for (int i = 0; i < count; i++) {
            QPointF point = points.at(i);
            double x = point.x() + penWidth / 1.2;
            painter->drawLine(QPointF(x, point.y()), QPointF(x, height()));
        }
    }

    painter->restore();
}

void WaveData::drawLine(QPainter *painter)
{
    if (!showLine || position > length || data.count() <= 0) {
        return;
    }

    painter->save();

    QPen pen;
    pen.setWidth(lineWidth);
    pen.setColor(lineColor);
    painter->setPen(pen);

    //计算当前位置对应的坐标
    int x = ((double)position / length) * width();
    painter->drawLine(x, 0, x, height());

    painter->restore();
}

Sixth, the controls described

  1. More than 150 exquisite control, covers a variety of dashboards, progress bar, the progress of the ball, compass, graphs, scales, thermometers, navigation bar, navigation bar, flatui, highlight the button, slide the selector, the lunar calendar and so on. Qwt far more than the number of controls integration.
  2. Each class can be independently as a separate control, zero coupling each control file and a header file to achieve a code amount, independent of other files to facilitate individual control integrated into the project source code form, less. qwt interlocking control class, highly coupled, want to use one of the controls, must contain all the code.
  3. Write all pure Qt, QWidget + QPainter to draw, to support any Qt version Qt4.6 Qt5.13, support for mingw, msvc, gcc compiler, etc., support any operating system such as windows + linux + mac + embedded linux, which does not garbled can be directly integrated into Qt Creator, a built-in controls and use the same, most of the effects can be as long as several properties are set, very convenient.
  4. DEMO separate source containing the control corresponding to each control has a convenient reference. It also provides integrated use of all controls a DEMO.
  5. Source code for each control has detailed Chinese annotation, are prepared in accordance with unified design specifications, easy to learn to write custom controls.
  6. Each control default color and demo corresponding color is very beautiful.
  7. More than 130 visible control, six invisible control.
  8. Portion control provides a variety of styles style selection, multiple choice style indicator.
  9. All controls changes adaptive stretched form.
  10. Integrated design custom attribute that supports drag design, WYSIWYG support the import and export in xml format.
  11. Activex control that comes with demo, all controls can be run directly in the browser ie.
  12. Fontawesome integrated graphics font + Alibaba iconfont collection of hundreds of graphic fonts, font fun graphic brings.
  13. All controls and finally generate a dynamic library files (dll or so, etc.) can be integrated directly into qtcreator designed for use in drag.
  14. Already qml version, the latter will consider a pyqt version, if the user is in great demand then.
  15. Custom plug-in open dynamic library (permanent free), and the back door without any restrictions, ease of use.
  16. 26 now available version dll, which includes qt5.12.3 msvc2017 32 + 64 mingw 32 + 64 in.
  17. From time to time to increase control and improve controls, regularly updated SDK, to welcome all suggestions, thank you!
  18. Qt introductory books recommended Huo Yafei of "Qt Creator Quick Start" "Qt5 programming entry", Qt official Advanced book recommendations "C ++ GUI Qt4 programming."
  19. Highly recommended programmer self-discipline and planning book series "lying programmer" "Programmer's growth course", "grief programmer", benefited from a lifetime!
  20. SDK download link: https://pan.baidu.com/s/1A5Gd77kExm8Co5ckT51vvQ extraction code: 877p

Guess you like

Origin www.cnblogs.com/feiyangqingyun/p/11583422.html