数据系列 - QwtSeriesData
QwtSeriesData 是绘图项数据的抽象接口,为绘图提供数据访问方法。通过自定义 QwtSeriesData 派生类,可以实现灵活的数据管理方式,支持从内存、文件、数据库等各种数据源获取绘图数据。
主要功能特性
特性
- ✅ 数据抽象接口:定义统一的数据访问接口
- ✅ 多种内置实现:提供内存存储、外部数组引用等常用实现
- ✅ 动态数据支持:支持实时更新和大数据场景
- ✅ 边界计算:自动计算数据边界矩形
庺本概念
数据接口结构
classDiagram
class QwtSeriesData~T~ {
+size() int
+sample(i) T
+boundingRect() QRectF
+setRectOfInterest(rect)
}
class QwtPointSeriesData {
+setSamples()
+samples()
}
class QwtArraySeriesData~T~ {
+setSamples()
+samples()
}
class QwtSyntheticSeriesData {
+value(x) double
}
QwtSeriesData <|-- QwtPointSeriesData
QwtSeriesData <|-- QwtArraySeriesData
QwtSeriesData <|-- QwtSyntheticSeriesData
内置数据类
| 类名 |
说明 |
QwtPointSeriesData |
存储QPointF数据点 |
QwtArraySeriesData<T> |
存储任意类型数据数组 |
QwtSyntheticSeriesData |
生成函数数据(不存储) |
使用方法
1. 使用内置数据类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | #include <QwtPlotCurve>
#include <QwtPointSeriesData>
QwtPlotCurve* curve = new QwtPlotCurve();
// 方法1:直接使用QwtPlotCurve的便捷方法
QVector<double> xData, yData;
curve->setSamples(xData, yData);
// 方法2:使用QwtPointSeriesData
QwtPointSeriesData* seriesData = new QwtPointSeriesData();
QVector<QPointF> points;
points << QPointF(0, 0) << QPointF(1, 1) << QPointF(2, 4);
seriesData->setSamples(points);
curve->setData(seriesData);
|
2. 引用外部数据
| #include <QwtPlotCurve>
QwtPlotCurve* curve = new QwtPlotCurve();
// 使用setRawSamples引用外部数组(不复制)
double x[1000], y[1000];
curve->setRawSamples(x, y, 1000);
// 注意:数组必须在curve存在期间保持有效
// 数据变化时无需重新设置,直接replot即可
|
setRawSamples注意事项
- 外部数组必须保持有效直到曲线销毁
- 不要修改数组大小,只修改内容
- 数据更新后需调用replot刷新显示
3. 自定义数据类
实现自定义数据源:
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 | #include <QwtSeriesData>
// 自定义数据库数据源
class DatabaseSeriesData : public QwtSeriesData<QPointF>
{
public:
DatabaseSeriesData(const QString& tableName)
: m_tableName(tableName)
{
// 初始化数据库连接
m_count = queryCount();
}
// 返回数据点数量
virtual size_t size() const override
{
return m_count;
}
// 返回指定索引的数据点
virtual QPointF sample(size_t i) const override
{
// 从数据库查询第i条记录
return queryPoint(i);
}
// 计算数据边界
virtual QRectF boundingRect() const override
{
if (m_boundingRect.isNull()) {
// 计算边界矩形
m_boundingRect = calculateBounds();
}
return m_boundingRect;
}
private:
QString m_tableName;
size_t m_count;
QRectF m_boundingRect;
size_t queryCount() const;
QPointF queryPoint(size_t i) const;
QRectF calculateBounds() const;
};
// 使用自定义数据类
curve->setData(new DatabaseSeriesData("measurements"));
|
4. 函数生成数据
使用 QwtSyntheticSeriesData 生成函数曲线:
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 | #include <QwtSyntheticSeriesData>
// 函数数据生成器
class FunctionSeriesData : public QwtSyntheticSeriesData
{
public:
FunctionSeriesData(double(*func)(double), double xMin, double xMax)
: QwtSyntheticSeriesData(xMin, xMax)
, m_function(func)
{
}
// 返回指定x位置的y值
virtual double value(double x) const override
{
return m_function(x);
}
private:
double(*m_function)(double);
};
// 使用函数生成数据
double myFunction(double x) {
return std::sin(x) * std::cos(2 * x);
}
curve->setData(new FunctionSeriesData(myFunction, 0, 10));
|
5. 实时数据更新
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 | // 实时数据场景
class RealtimeSeriesData : public QwtSeriesData<QPointF>
{
public:
RealtimeSeriesData(int maxPoints = 1000)
: m_maxPoints(maxPoints)
{
}
void appendPoint(const QPointF& point)
{
m_points.append(point);
if (m_points.size() > m_maxPoints) {
m_points.removeFirst();
}
m_boundingRect = QRectF(); // 重置边界,触发重新计算
}
virtual size_t size() const override { return m_points.size(); }
virtual QPointF sample(size_t i) const override { return m_points[i]; }
virtual QRectF boundingRect() const override
{
if (m_boundingRect.isNull()) {
m_boundingRect = calculateBounds();
}
return m_boundingRect;
}
private:
QVector<QPointF> m_points;
int m_maxPoints;
QRectF m_boundingRect;
};
// 使用
RealtimeSeriesData* data = new RealtimeSeriesData(1000);
curve->setData(data);
// 实时添加数据
data->appendPoint(QPointF(time, value));
plot->replot();
|
核心方法总结
QwtSeriesData接口
| 方法 |
说明 |
size() |
返回数据点数量 |
sample(i) |
返回第i个数据点 |
boundingRect() |
返回数据边界矩形 |
setRectOfInterest() |
设置感兴趣区域(优化渲染) |
QwtPlotCurve数据方法
| 方法 |
说明 |
setData() |
设置数据对象 |
setSamples() |
设置数据数组 |
setRawSamples() |
引用外部数组 |
data() |
获取数据对象 |
数据管理建议
- 静态数据:使用
setSamples() 复制数据
- 大数据:使用
setRawSamples() 避免复制
- 动态数据:实现自定义
QwtSeriesData
- 函数数据:使用
QwtSyntheticSeriesData
相关示例
- 实时数据:
examples/2D/realtime
- CPU监控:
examples/2D/cpuplot