Qt图表功能学习
Qt图表功能学习
1. 项目概述
本项目展示了如何使用Qt Charts模块创建图表,实现温度与时间的曲线关系展示。Qt Charts是Qt提供的一个强大的图表绘制模块,可以方便地创建各种类型的图表,如折线图、曲线图、柱状图、饼图等。
1.1 项目结构
47/
├── 47.pro # 项目配置文件
├── main.cpp # 主函数入口
├── widget.h # Widget类头文件
├── widget.cpp # Widget类实现文件
└── widget.ui # 界面设计文件
1.2 功能特点
- 创建温度与时间的曲线图表
- 设置坐标轴范围和标题
- 自定义曲线样式和颜色
- 使用QSplineSeries创建平滑曲线
2. 代码实现
2.1 项目配置文件 (47.pro)
QT += core gui chartsgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0SOURCES += \main.cpp \widget.cppHEADERS += \widget.hFORMS += \widget.ui# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
关键点说明:
QT += charts
- 添加Qt Charts模块支持,这是使用图表功能的必要配置
2.2 主函数 (main.cpp)
#include "widget.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}
2.3 Widget类头文件 (widget.h)
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QChart> // 图表类
#include <QChartView> // 图表视图类QT_CHARTS_USE_NAMESPACE // using namespace QT_CHARTS_NAMESPACEQT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;
};
#endif // WIDGET_H
关键点说明:
#include <QChart>
和#include <QChartView>
- 包含图表相关的头文件QT_CHARTS_USE_NAMESPACE
- 使用Qt Charts命名空间,避免每次使用图表类时都要加上命名空间前缀
2.4 Widget类实现文件 (widget.cpp)
#include "widget.h"
#include "ui_widget.h"
#include <QValueAxis> // 数值坐标轴
#include <QSplineSeries> // 曲线
//#include <QLineSeries> // 折线Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 1.创建一个图表视图// QChartView *chartView = new QChartView();// 2.创建一个图表QChart *chart = new QChart();// 3.创建坐标轴QValueAxis *valueAxisX = new QValueAxis();QValueAxis *valueAxisY = new QValueAxis();// 4.设置坐标轴的范围valueAxisX->setRange(0, 5000);valueAxisY->setRange(0, 100);// 5.设置坐标轴的标题和显示的格式valueAxisX->setTitleText("时间/ms");valueAxisY->setTitleText("温度/°C");valueAxisX->setLabelFormat("%d");valueAxisY->setLabelFormat("%d");// 设置xy的显示的格式// valueAxisX->setTickCount(10);// valueAxisY->setTickCount(10);// 6.图表添加坐标轴chart->createDefaultAxes();chart->addAxis(valueAxisX, Qt::AlignBottom);chart->addAxis(valueAxisY, Qt::AlignLeft);// 7.设置图表的标题以及图例显示是否需要chart->setTitle("温度与时间曲线");chart->legend()->setVisible(false);// 8.创建曲线对象添加它的点,设置曲线的颜色QSplineSeries *splineSeries = new QSplineSeries();splineSeries->append(0, 50);splineSeries->append(1000, 60);splineSeries->append(2000, 80);splineSeries->append(3000, 50);splineSeries->append(4000, 30);splineSeries->append(5000, 80);QPen pen(QColor(0xff5566));splineSeries->setPen(pen);// 9.图表添加曲线chart->addSeries(splineSeries);// 10.!!!!将曲线的数据与坐标轴相连!!!!注意,这个要在图表添加曲线之后// 附属到坐标轴上面去splineSeries->attachAxis(valueAxisX);splineSeries->attachAxis(valueAxisY);// 11.将图表放置于图表视图ui->chartView->setChart(chart);
}Widget::~Widget()
{delete ui;
}
关键点说明:
-
图表创建流程:
- 创建图表对象
QChart
- 创建坐标轴
QValueAxis
- 设置坐标轴范围和标题
- 将坐标轴添加到图表
- 设置图表标题和图例
- 创建曲线并添加数据点
- 设置曲线样式
- 将曲线添加到图表
- 将曲线与坐标轴关联
- 将图表设置到图表视图
- 创建图表对象
-
坐标轴设置:
setRange(min, max)
- 设置坐标轴范围setTitleText(text)
- 设置坐标轴标题setLabelFormat(format)
- 设置坐标轴标签格式setTickCount(count)
- 设置刻度数量
-
曲线设置:
QSplineSeries
- 创建平滑曲线append(x, y)
- 添加数据点setPen(pen)
- 设置曲线样式attachAxis(axis)
- 将曲线与坐标轴关联
2.5 界面设计文件 (widget.ui)
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>Widget</class><widget class="QWidget" name="Widget"><property name="geometry"><rect><x>0</x><y>0</y><width>800</width><height>480</height></rect></property><property name="windowTitle"><string>Widget</string></property><layout class="QVBoxLayout" name="verticalLayout"><item><widget class="QLabel" name="label"><property name="text"><string>QChart图表示例</string></property><property name="alignment"><set>Qt::AlignCenter</set></property></widget></item><item><widget class="QChartView" name="chartView"/></item></layout></widget><customwidgets><customwidget><class>QChartView</class><extends>QGraphicsView</extends><header>qchartview.h</header></customwidget></customwidgets><resources/><connections/>
</ui>
关键点说明:
- 界面使用垂直布局,包含一个标签和一个图表视图
QChartView
是一个自定义控件,继承自QGraphicsView
- 需要包含头文件
qchartview.h
3. Qt Charts模块详解
3.1 常用图表类型
类名 | 描述 | 用途 |
---|---|---|
QLineSeries | 折线图 | 显示离散数据点之间的直线连接 |
QSplineSeries | 曲线图 | 显示平滑曲线连接的数据点 |
QScatterSeries | 散点图 | 显示不连接的离散数据点 |
QBarSeries | 柱状图 | 显示分类数据的柱状表示 |
QPieSeries | 饼图 | 显示数据占比的圆形表示 |
QAreaSeries | 面积图 | 显示数据区域填充的图表 |
3.2 坐标轴类型
类名 | 描述 | 用途 |
---|---|---|
QValueAxis | 数值坐标轴 | 显示数值型数据 |
QDateTimeAxis | 日期时间坐标轴 | 显示日期和时间 |
QCategoryAxis | 类别坐标轴 | 显示分类数据 |
QLogValueAxis | 对数坐标轴 | 显示对数刻度 |
4. 实现步骤详解
4.1 添加Charts模块
在项目文件(.pro)中添加:
QT += charts
4.2 包含必要的头文件
#include <QChart>
#include <QChartView>
#include <QValueAxis>
#include <QSplineSeries> // 或其他系列类型QT_CHARTS_USE_NAMESPACE // 使用Qt Charts命名空间
4.3 创建图表的基本步骤
- 创建图表和坐标轴
// 创建图表
QChart *chart = new QChart();// 创建坐标轴
QValueAxis *axisX = new QValueAxis();
QValueAxis *axisY = new QValueAxis();// 设置坐标轴范围
axisX->setRange(0, 10);
axisY->setRange(0, 100);// 设置坐标轴标题
axisX->setTitleText("X轴");
axisY->setTitleText("Y轴");// 添加坐标轴到图表
chart->addAxis(axisX, Qt::AlignBottom);
chart->addAxis(axisY, Qt::AlignLeft);
- 创建数据系列并添加数据
// 创建曲线系列
QSplineSeries *series = new QSplineSeries();// 添加数据点
series->append(0, 10);
series->append(1, 20);
series->append(2, 30);
// ...// 设置系列名称(用于图例)
series->setName("数据系列1");// 自定义系列外观
QPen pen(QColor(0x00, 0x80, 0x80));
pen.setWidth(2);
series->setPen(pen);// 添加系列到图表
chart->addSeries(series);// 将系列附加到坐标轴
series->attachAxis(axisX);
series->attachAxis(axisY);
- 设置图表属性
// 设置图表标题
chart->setTitle("我的图表");// 设置图例可见性
chart->legend()->setVisible(true);
// 设置图例位置
chart->legend()->setAlignment(Qt::AlignBottom);// 设置图表主题
chart->setTheme(QChart::ChartThemeBlueCerulean);// 设置动画
chart->setAnimationOptions(QChart::AllAnimations);
- 将图表添加到视图
// 方法1:使用已有的QChartView控件(如UI设计中添加的)
ui->chartView->setChart(chart);// 方法2:创建新的QChartView
QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing); // 抗锯齿
5. 常用功能示例
5.1 动态添加数据点
// 假设我们有一个定时器,每秒添加一个新的数据点
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, [=]() {// 获取最后一个点的x值qreal lastX = 0;if (!series->points().isEmpty()) {lastX = series->points().last().x();}// 生成新的数据点qreal newX = lastX + 1;qreal newY = QRandomGenerator::global()->bounded(100); // 随机值// 添加到系列series->append(newX, newY);// 如果需要,调整X轴范围以显示最新数据if (newX > axisX->max()) {axisX->setRange(axisX->min() + 1, newX);}
});// 启动定时器,每秒触发一次
timer->start(1000);
5.2 多个数据系列
// 创建第一个系列
QSplineSeries *series1 = new QSplineSeries();
series1->setName("温度1");
series1->append(0, 10);
series1->append(1, 20);
// ...// 创建第二个系列
QSplineSeries *series2 = new QSplineSeries();
series2->setName("温度2");
series2->append(0, 15);
series2->append(1, 25);
// ...// 设置不同颜色
series1->setPen(QPen(QColor(0xff, 0x55, 0x66), 2));
series2->setPen(QPen(QColor(0x55, 0x66, 0xff), 2));// 添加到图表
chart->addSeries(series1);
chart->addSeries(series2);// 附加到坐标轴
series1->attachAxis(axisX);
series1->attachAxis(axisY);
series2->attachAxis(axisX);
series2->attachAxis(axisY);
5.3 自定义图表主题
// 设置预定义主题
chart->setTheme(QChart::ChartThemeDark); // 深色主题// 或者自定义图表背景
QLinearGradient backgroundGradient;
backgroundGradient.setStart(QPointF(0, 0));
backgroundGradient.setFinalStop(QPointF(0, 1));
backgroundGradient.setColorAt(0.0, QRgb(0x2F2F3F));
backgroundGradient.setColorAt(1.0, QRgb(0x1F1F2F));
backgroundGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
chart->setBackgroundBrush(backgroundGradient);// 自定义图表边框
chart->setBackgroundPen(QPen(QRgb(0x3F3F4F)));
5.4 图表交互
// 启用图表交互功能
QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);// 启用缩放和平移
chartView->setRubberBand(QChartView::RectangleRubberBand);
chartView->setInteractive(true);// 处理点击事件(需要自定义QChartView子类)
class CustomChartView : public QChartView {
public:CustomChartView(QChart *chart, QWidget *parent = nullptr): QChartView(chart, parent) {}protected:void mousePressEvent(QMouseEvent *event) override {QPointF pos = chart()->mapToValue(event->pos());qDebug() << "Clicked at:" << pos;// 查找最近的点for (auto series : chart()->series()) {QXYSeries *xySeries = qobject_cast<QXYSeries*>(series);if (xySeries) {// 查找最近的点逻辑...}}QChartView::mousePressEvent(event);}
};