一、 概念
LineSeries
是 QML 中 ChartView
提供的一种图表系列类型,用于绘制折线图。它通过一系列点来绘制一条线,这些点可以表示数据的变化趋势。LineSeries
是 ChartView
中最常用的系列类型之一,适用于展示数据随时间或顺序的变化
二、功能特点
-
数据点集合 :
LineSeries
使用一系列点来绘制折线图,每个点由x
和y
值组成。 -
动态更新:可以动态添加、删除或更新数据点,使图表能够实时反映数据变化。
-
样式自定义:可以通过设置属性来自定义线条的颜色、宽度、点的样式等。
-
交互性 :支持鼠标悬停、点击等交互操作,可以结合
Tooltip
提供更多数据信息。 -
数据绑定 :可以绑定到数据模型(如
QAbstractSeries
或QList<QPointF>
),实现数据的动态更新。
三、 使用方法
3.1、最小可运行代码,运行即可看到带标题、动画过渡的折线图
QT += core gui widgets charts qml quick
#include <QApplication>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
import QtQuick 2.15
import QtQuick.Window 2.15
import QtCharts 2.15
Window {
visible: true
width: 640; height: 480
title: qsTr("ChartView 最小示例")
ChartView {
anchors.fill: parent
title: "温度"
LineSeries {
name: "T"
XYPoint { x: 0; y: 20 }
XYPoint { x: 1; y: 25 }
XYPoint { x: 2; y: 23 }
}
}
}
3.2、数据绑定与动态更新
方案 A:在 纯 QML 里用 Timer
定时追加数据
import QtQuick 2.15
import QtQuick.Window 2.15
import QtCharts 2.15
Window {
visible: true
width: 640; height: 480
title: qsTr("ChartView 实时刷新")
ChartView {
id: chart
anchors.fill: parent
title: "温度"
animationOptions: ChartView.SeriesAnimations // 开启动画
// X、Y 轴
ValueAxis {
id: axisX
min: 0
max: 10 // 初始横轴 10 个点
titleText: "采样次数"
}
ValueAxis {
id: axisY
min: 15
max: 35
titleText: "温度 (°C)"
}
LineSeries {
id: series
name: "T"
axisX: axisX
axisY: axisY
}
}
/* ---------- 定时刷新 ---------- */
Timer {
interval: 800 // 800 ms 一次
running: true
repeat: true
onTriggered: {
const x = series.count // 当前点数
const y = 20 + Math.random()*10 // 模拟 20~30 °C
series.append(x, y)
// 简单的滚动窗口:超过 10 个点就整体右移
if (x > 10) {
axisX.min += 1
axisX.max += 1
}
}
}
}
方案 B:在 C++ 里用信号触发刷新
(适合真正的大数据/硬件采集,UI 不卡顿)
#ifndef DATASOURCE_H
#define DATASOURCE_H
#include <QObject>
#include <QTimer>
#include <QRandomGenerator>
// dataSource.h
class DataSource : public QObject {
Q_OBJECT
public:
explicit DataSource(QObject *parent = nullptr) : QObject(parent) {
m_timer.setInterval(500);
connect(&m_timer, &QTimer::timeout, this, &DataSource::generate);
m_timer.start();
}
signals:
void newPoint(qreal x, qreal y);
private:
void generate() {
static int i = 0;
emit newPoint(i++, 20 + QRandomGenerator::global()->generateDouble()*10);
}
QTimer m_timer;
};
#endif // DATASOURCE_H
#include <QApplication>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <DataSource.h>
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QApplication app(argc, argv);
QQmlApplicationEngine engine;
DataSource src;
engine.rootContext()->setContextProperty("dataSrc", &src);
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
import QtQuick 2.15
import QtQuick.Window 2.15
import QtCharts 2.15
Window {
visible: true
width: 640; height: 480
title: qsTr("ChartView 实时刷新")
ChartView {
id: chart
anchors.fill: parent
title: "温度"
animationOptions: ChartView.SeriesAnimations // 开启动画
// X、Y 轴
ValueAxis {
id: axisX
min: 0
max: 10 // 初始横轴 10 个点
titleText: "采样次数"
}
ValueAxis {
id: axisY
min: 15
max: 35
titleText: "温度 (°C)"
}
LineSeries {
id: series
name: "T"
axisX: axisX
axisY: axisY
}
}
Connections {
target: dataSrc
function onNewPoint(x, y) {
series.append(x, y);
if (x > 10) {
axisX.min += 1;
axisX.max += 1;
}
}
}
}
3.3、自定义样式
可以通过设置属性来自定义线条的颜色、宽度等:
ChartView {
width: 600
height: 300
title: "自定义折线图"
series: [
LineSeries {
name: "自定义系列"
color: "red" // 设置线条颜色
lineCap: LineSeries.RoundCap // 设置线条端点样式
lineJoin: LineSeries.RoundJoin // 设置线条连接点样式
points: [
{ x: 1, y: 5 },
{ x: 2, y: 10 },
{ x: 3, y: 15 },
{ x: 4, y: 20 },
{ x: 5, y: 25 }
]
}
]
}
3.4、常用属性和方法
-
points :一个包含点的数组,每个点是一个对象,包含
x
和y
属性。 -
color:设置线条的颜色。
-
lineWidth:设置线条的宽度。
-
lineCap :设置线条端点的样式,可选值为
LineSeries.FlatCap
、LineSeries.RoundCap
、LineSeries.SquareCap
。 -
lineJoin :设置线条连接点的样式,可选值为
LineSeries.MiterJoin
、LineSeries.RoundJoin
、LineSeries.BevelJoin
。 -
smooth:设置是否平滑绘制线条。
-
append(x, y):动态添加一个点。
-
remove(index):移除指定索引的点。
-
clear():清除所有点。
四、注意事项
4.1、坐标轴
ChartView 不会自动创建轴,需要手动声明并绑定:
ValueAxis {
id: axisX
min: 0; max: 10
tickCount: 6
}
ValueAxis {
id: axisY
min: 0; max: 100
}
LineSeries {
axisX: axisX
axisY: axisY
}
4.2、大数据刷新
在大数据量(场景下,ChartView 的动画、抗锯齿、OpenGL 加速等设置都会影响性能。
-
真·实时刷新 超过几万点后,
append()
会开始卡顿。建议:
• 使用
replace()
替换整条数组,而不是逐点append()
• 或者自己实现降采样(只保留最新 N 点)。
-
Qt 版本差异
•
useOpenGL
在 Qt 6 已经废弃,Qt 6 默认就是 GPU 管线,无需设置。• 若用 Qt 6,只需
animationOptions: ChartView.NoAnimation
即可。import QtQuick 2.15
import QtQuick.Window 2.15
import QtCharts 2.15Window {
visible: true
width: 800; height: 500
title: qsTr("大数据折线图,需等待")ChartView { id: chart anchors.fill: parent title: "温度曲线" animationOptions: ChartView.NoAnimation // 关动画 antialiasing: false // 关抗锯齿 ValueAxis { id: axisX; min: 0; max: 10000 } ValueAxis { id: axisY; min: 15; max: 35 } LineSeries { id: series axisX: axisX axisY: axisY useOpenGL: true // 用 GPU } } Component.onCompleted: { for (let i = 0; i < 10000; ++i) series.append(i, 20 + Math.sin(i * 0.01) * 5); }
}
设置 | 作用 | 备注 |
---|---|---|
animationOptions: ChartView.NoAnimation |
彻底关闭系列动画,减少 CPU/GPU 负载 | 大数据必备 |
antialiasing: false |
关闭边缘平滑,每帧少一次全屏混合 | 视觉略差,性能提升明显 |
renderTarget: ChartView.GL |
让 ChartView 整体用 OpenGL 渲染 | Qt 5.11+ 支持 |
LineSeries.useOpenGL: true |
把折线交给 GPU 画 | 必须 与上一条一起用 |
LineSeries
是 QML 中 ChartView
的一个强大组件,适用于绘制折线图。它支持动态数据更新、样式自定义和交互操作,能够满足多种数据可视化需求。