ChartView的LineSeries 基本介绍与使用

一、 概念

LineSeries 是 QML 中 ChartView 提供的一种图表系列类型,用于绘制折线图。它通过一系列点来绘制一条线,这些点可以表示数据的变化趋势。LineSeriesChartView 中最常用的系列类型之一,适用于展示数据随时间或顺序的变化

二、功能特点
  • 数据点集合LineSeries 使用一系列点来绘制折线图,每个点由 xy 值组成。

  • 动态更新:可以动态添加、删除或更新数据点,使图表能够实时反映数据变化。

  • 样式自定义:可以通过设置属性来自定义线条的颜色、宽度、点的样式等。

  • 交互性 :支持鼠标悬停、点击等交互操作,可以结合 Tooltip 提供更多数据信息。

  • 数据绑定 :可以绑定到数据模型(如 QAbstractSeriesQList<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 :一个包含点的数组,每个点是一个对象,包含 xy 属性。

  • color:设置线条的颜色。

  • lineWidth:设置线条的宽度。

  • lineCap :设置线条端点的样式,可选值为 LineSeries.FlatCapLineSeries.RoundCapLineSeries.SquareCap

  • lineJoin :设置线条连接点的样式,可选值为 LineSeries.MiterJoinLineSeries.RoundJoinLineSeries.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 加速等设置都会影响性能。

  1. 真·实时刷新 超过几万点后,append() 会开始卡顿。

    建议:

    • 使用 replace() 替换整条数组,而不是逐点 append()

    • 或者自己实现降采样(只保留最新 N 点)。

  2. Qt 版本差异

    useOpenGL 在 Qt 6 已经废弃,Qt 6 默认就是 GPU 管线,无需设置。

    • 若用 Qt 6,只需 animationOptions: ChartView.NoAnimation 即可。

    import QtQuick 2.15
    import QtQuick.Window 2.15
    import QtCharts 2.15

    Window {
    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 的一个强大组件,适用于绘制折线图。它支持动态数据更新、样式自定义和交互操作,能够满足多种数据可视化需求。

相关推荐
LoveXming6 小时前
Chapter1—设计模式基础
c++·qt·设计模式·设计规范
歪歪1008 小时前
如何在Qt Creator中快速定位代码中的注释?
运维·开发语言·qt·解释器模式·全文检索·嵌入式实时数据库
学生董格9 小时前
[嵌入式embed][Qt]Qt5.12+Opencv4.x+Cmake4.x_用Qt编译linux-Opencv库 & 测试
linux·qt·opencv
码农客栈9 小时前
Qt读写Excel--QXlsx基本使用
qt·excel
ajassi200010 小时前
开源 C++ QT Widget 开发(十二)图表--环境监测表盘
c++·qt·开源
edge014 小时前
Qt 项目中集成 qBreakpad 生成崩溃 dump 文件
qt
津津有味道20 小时前
15693协议ICODE SLI 系列标签应用场景说明及读、写、密钥认证操作Qt c++源码,支持统信、麒麟等国产Linux系统
linux·c++·qt·icode·sli·15693
秋风&萧瑟1 天前
【QT】Qt QSS 中 background-image、image 和 border-image 的区别
开发语言·qt
DIY机器人工房1 天前
问题解决方法:qt的设计师页面怎么开启scroll area组件的滚轮功能
qt·嵌入式·diy机器人工房