Content Table

使用 QChart 创建平滑曲线

绘制平滑曲线 一节介绍了使用算法实现平滑曲线,Qt 5.7 后提供了 charts 模块,使用 QSplineSeries 就能很轻松的实现平滑曲线了,而且效果很好,但是需要注意一点的是,免费版的 Qt 中 charts 模块是 GPL 协议的。

实现如图效果的平滑曲线,只需要简单的几步就可以做到,具体请参考下面的代码

为了显示平滑曲线,分为以下几步
  1. 创建 QSplineSeries 对象 splineSeries,并且把曲线上点的坐标添加到 splineSeries,QSplineSeries 会自动的计算曲线的控制点,这些控制点是绘制平滑曲线的关键,就像前面的文章中我们使用算法计算的控制点那样,只不过我们当时提供的算法不是很好

    1
    2
    QSplineSeries *splineSeries = new QSplineSeries();
    splineSeries->append(0, 6);
  2. 曲线的数据准备好后,需要放在一个 QChart 里显示,一个 QChart 可以同时显示几个 Series

    1
    2
    QChart *chart = new QChart();
    chart->addSeries(splineSeries);
  3. 最后,用 QChart 来创建一个 QChartView,最终显示给用户,QChartView 也可以作为另一个 Widget 的子 Widget

    1
    QChartView *chartView = new QChartView(chart);

主要的几个类关系如下:

示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <QApplication>
#include <QWidget>
#include <QChartView>
#include <QSplineSeries>
#include <QScatterSeries>
#include <QChart>
#include <QHBoxLayout>

using namespace QtCharts;

int main(int argc, char *argv[]) {
QApplication a(argc, argv);

// 创建平滑曲线上点的序列
QSplineSeries *splineSeries = new QSplineSeries();
splineSeries->setName("spline");

splineSeries->append(0, 6);
splineSeries->append(2, 4);
splineSeries->append(3, 8);
splineSeries->append(7, 4);
splineSeries->append(10, 5);
*splineSeries << QPointF(11, 1) << QPointF(13, 3) << QPointF(17, 6) << QPointF(18, 3) << QPointF(20, 2);

// 创建散列点的序列
QScatterSeries *scatterSeries = new QScatterSeries();
scatterSeries->setMarkerSize(8);
scatterSeries->append(0, 6);
scatterSeries->append(2, 4);
scatterSeries->append(3, 8);
scatterSeries->append(7, 4);
scatterSeries->append(10, 5);
*scatterSeries << QPointF(11, 1) << QPointF(13, 3) << QPointF(17, 6) << QPointF(18, 3) << QPointF(20, 2);

// 使用点的序列创建图表: 标题, 坐标轴, 图例都是属于图表的
QChart *chart = new QChart();
chart->addSeries(splineSeries);
chart->addSeries(scatterSeries);
chart->legend()->hide();
chart->setTitle("平滑曲线");
chart->createDefaultAxes(); // 默认没有创建坐标轴,addSeries 后才创建坐标轴。创建坐标轴后再添加的 series 显示不正确。
QList<QAbstractAxis *> yAxes = chart->axes(Qt::Vertical, splineSeries);
yAxes[0]->setRange(0, 10);

// 显示图标的 view
QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);

// Widget 相关
QHBoxLayout *layout = new QHBoxLayout();
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(chartView);

QWidget w;
w.setWindowTitle("QChart 实现的平滑曲线");
w.resize(600, 300);
w.setLayout(layout);
w.show();

return a.exec();
}

更多信息请参考 Qt 自带的例子,搜索 chart example