Qt Charts 库使用指南
Qt Charts 是 Qt 官方提供的图表模块,支持创建各种交互式数据可视化图表。
官方示例:QtCreator页面》左上角欢迎》点击示例》搜索chart
一、环境配置详解
1. Qt 版本要求
- Qt 5.7+:需手动安装 charts 模块
- Qt 6.0+:已集成在核心模块中
2. 项目配置
# .pro 文件
QT += core gui charts
# 启用 C++17 特性(推荐)
CONFIG += c++17
3. 头文件包含
// 推荐按需包含(减少编译时间)
#include <QtCharts/QChartView>
#include <QtCharts/QLineSeries>
#include <QtCharts/QBarSeries>
#include <QtCharts/QValueAxis>
// 或者全局包含
#include <QtCharts>
using namespace QtCharts;
二、核心架构解析
1. 组件层级关系
QChartView (视图容器)
├── QChart (图表主体)
│ ├── QAbstractSeries (数据系列)
│ │ ├── QLineSeries
│ │ ├── QBarSeries
│ │ └── QPieSeries
│ └── QAbstractAxis (坐标轴)
│ ├── QValueAxis
│ └── QBarCategoryAxis
└── QLegend (图例)
2. 核心类功能
类名 | 关键方法 | 说明 |
---|---|---|
QChart | addSeries() , createDefaultAxes() , setTheme() | 图表容器,管理所有元素 |
QChartView | setRubberBand() , setRenderHint() | 显示容器,处理交互 |
QXYSeries | append() , replace() , clear() | 基础数据序列(折线/散点图) |
QBarSeries | append() , barSets() , setLabelsVisible() | 柱状图序列 |
QPieSeries | append() , slices() , setPieSize() | 饼图序列 |
QValueAxis | setRange() , setTickCount() , setTitleText() | 数值坐标轴 |
三、完整图表实现示例
1. 动态折线图(带实时更新)
// 创建图表
QChart *chart = new QChart();
chart->setTitle("实时数据监控");
chart->setAnimationOptions(QChart::SeriesAnimations);
// 创建序列
QLineSeries *series = new QLineSeries();
series->setName("温度传感器");
// 模拟实时数据
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, [=](){
static int x = 0;
double y = QRandomGenerator::global()->bounded(20.0, 30.0);
series->append(x++, y);
// 自动滚动视图
if(x > 20) {
chart->axisX()->setRange(x-20, x);
}
});
timer->start(1000); // 每秒更新
// 坐标轴
QValueAxis *axisX = new QValueAxis;
axisX->setTitleText("时间 (s)");
axisX->setRange(0, 20);
QValueAxis *axisY = new QValueAxis;
axisY->setTitleText("温度 (°C)");
axisY->setRange(15, 35);
// 添加到图表
chart->addSeries(series);
chart->addAxis(axisX, Qt::AlignBottom);
chart->addAxis(axisY, Qt::AlignLeft);
series->attachAxis(axisX);
series->attachAxis(axisY);
// 显示
QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
2. 多系列柱状图
// 创建数据集
QBarSet *low = new QBarSet("低温");
QBarSet *high = new QBarSet("高温");
*low << 5 << 8 << 6 << 7;
*high << 12 << 15 << 13 << 14;
// 创建柱状序列
QBarSeries *series = new QBarSeries();
series->append(low);
series->append(high);
series->setLabelsVisible(true);
series->setLabelsFormat("@value°C");
// 图表设置
QChart *chart = new QChart();
chart->addSeries(series);
chart->setTitle("城市温度对比");
// 分类轴
QBarCategoryAxis *axisX = new QBarCategoryAxis();
axisX->append({"北京", "上海", "广州", "深圳"});
// 数值轴
QValueAxis *axisY = new QValueAxis();
axisY->setRange(0, 20);
chart->addAxis(axisX, Qt::AlignBottom);
chart->addAxis(axisY, Qt::AlignLeft);
series->attachAxis(axisX);
series->attachAxis(axisY);
// 图例设置
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignBottom);
3. 交互式饼图
QPieSeries *series = new QPieSeries();
series->append("Android", 72.9);
series->append("iOS", 16.5);
series->append("其他", 10.6);
// 切片设置
QPieSlice *androidSlice = series->slices().at(0);
androidSlice->setExploded(true);
androidSlice->setLabelVisible(true);
androidSlice->setLabelColor(Qt::white);
androidSlice->setBrush(QColor("#a4c639"));
// 点击事件
connect(series, &QPieSeries::clicked, [](QPieSlice *slice){
slice->setExploded(!slice->isExploded());
});
// 图表设置
QChart *chart = new QChart();
chart->addSeries(series);
chart->setTitle("移动操作系统市场份额");
chart->legend()->setAlignment(Qt::AlignRight);
四、高级功能实现
1. 混合图表(折线+柱状)
// 柱状序列
QBarSeries *barSeries = new QBarSeries();
QBarSet *set = new QBarSet("销量");
*set << 120 << 150 << 180 << 200;
barSeries->append(set);
// 折线序列
QLineSeries *lineSeries = new QLineSeries();
lineSeries->setName("增长率");
lineSeries->append(0, 15);
lineSeries->append(1, 25);
lineSeries->append(2, 20);
lineSeries->append(3, 10);
// 创建图表
QChart *chart = new QChart();
chart->addSeries(barSeries);
chart->addSeries(lineSeries);
// 双Y轴
QValueAxis *axisX = new QValueAxis;
axisX->setRange(0, 3);
QValueAxis *axisYLeft = new QValueAxis; // 左Y轴(销量)
axisYLeft->setRange(0, 250);
QValueAxis *axisYRight = new QValueAxis; // 右Y轴(增长率)
axisYRight->setRange(0, 30);
chart->addAxis(axisX, Qt::AlignBottom);
chart->addAxis(axisYLeft, Qt::AlignLeft);
chart->addAxis(axisYRight, Qt::AlignRight);
barSeries->attachAxis(axisX);
barSeries->attachAxis(axisYLeft);
lineSeries->attachAxis(axisX);
lineSeries->attachAxis(axisYRight);
2. 图表样式定制
// 自定义线型
QPen pen(Qt::red);
pen.setWidth(2);
pen.setStyle(Qt::DashDotLine);
series->setPen(pen);
// 渐变填充
QLinearGradient gradient(0, 0, 0, 1);
gradient.setColorAt(0, QColor("#2a82da"));
gradient.setColorAt(1, QColor("#1c5ca7"));
series->setBrush(gradient);
// 数据点样式
series->setPointLabelsFormat("(@xPoint, @yPoint)");
series->setPointLabelsVisible(true);
series->setPointLabelsFont(QFont("Arial", 8));
// 坐标轴样式
axisX->setGridLineColor(Qt::gray);
axisX->setGridLineVisible(true);
axisY->setLinePen(QPen(Qt::darkBlue, 2));
// 图表背景
chart->setBackgroundBrush(QBrush(QColor("#f0f0f0")));
3. 大数据优化策略
// 1. 禁用动画
chart->setAnimationOptions(QChart::NoAnimation);
// 2. 使用OpenGL加速(需系统支持)
QLineSeries *fastSeries = new QLineSeries();
fastSeries->setUseOpenGL(true); // 开启GPU加速
// 3. 数据采样(每10个点取1个)
const int sampleStep = 10;
QVector<QPointF> sampledData;
for(int i=0; i<rawData.size(); i+=sampleStep) {
sampledData.append(rawData[i]);
}
series->replace(sampledData);
// 4. 分页加载
const int pageSize = 1000;
void loadDataPage(int page) {
int start = page * pageSize;
int end = qMin(start + pageSize, totalSize);
series->append(getDataRange(start, end));
}
五、最佳实践与调试
1. 常见问题解决
-
数据不显示:
- 检查坐标轴是否关联
series->attachAxis(axis)
- 验证数据范围是否在坐标轴范围内
- 确认是否调用了
chartView->show()
- 检查坐标轴是否关联
-
内存泄漏:
// 正确管理对象树 QChartView *chartView = new QChartView(this); // 指定父对象 QChart *chart = new QChart(); // 自动成为chartView的子对象
-
中文乱码:
// 在main函数中设置 QApplication::setFont(QFont("Microsoft YaHei", 9));
2. 性能优化技巧
- 大数据集(>10,000点)启用OpenGL加速
- 禁用不必要的动画效果
- 使用
replace()
而非clear() + append()
更新数据 - 避免频繁的图表重绘(合并更新操作)
3. 推荐资源
- 官方文档
- 示例路径:
Qt/Examples/Qt-6.x/charts
- 调试工具:Qt Creator > 分析 > QML Profiler
六、扩展应用场景
1. 金融图表(K线图)
// 使用 QCandlestickSeries
QCandlestickSeries *series = new QCandlestickSeries();
series->setName("Apple Inc.");
// 添加K线数据
QCandlestickSet *set = new QCandlestickSet();
set->setTimestamp(time);
set->setOpen(open);
set->setHigh(high);
set->setLow(low);
set->setClose(close);
series->append(set);
// 时间轴
QDateTimeAxis *axisX = new QDateTimeAxis;
axisX->setFormat("MM-dd");
2. 科学图表(散点图)
QScatterSeries *series = new QScatterSeries();
series->setMarkerShape(QScatterSeries::MarkerShapeCircle);
series->setMarkerSize(10.0);
// 添加数据点
series->append(0.5, 1.5);
series->append(1.5, 2.5);
// 添加趋势线
QLineSeries *trendLine = new QLineSeries();
trendLine->append(0, 1);
trendLine->append(2, 3);
3. 仪表盘(结合QML)
import QtCharts 2.15
ChartView {
id: chart
theme: ChartView.ChartThemeDark
ValueAxis {
id: axis
min: 0
max: 100
}
PieSeries {
id: pieSeries
size: 0.7
holeSize: 0.6
PieSlice {
label: "使用率"
value: 75
color: "#4caf50"
}
}
}