要想使用 Qt Charts,我们的 Qt 版本得使用 Qt 5.7 之后的版本。其实 Qt Charts 并不是 Qt 5.7 才有的,是在 Qt 5.7 以前只有商业版本的 Qt 才有 Qt Charts。我们能免费下载的 Qt 版本都是社区(开源)版本。
Qt Charts 很方便的绘制我们常见的曲线图、折线图、柱状图和饼状图等图表。不用自己花精力去了解第三方组件的使用了或者开发第三方组件。Qt 的帮助文档里已经有说明 Qt Charts 主要部件的使用方法。需要用到时我们可以查看 Qt 文档就可以了。
下面我们主要简介一下 Qt Charts 模块,首先先看它的继承关系,(看继承关系可以了解这 个类是怎么来的,它不可能是一下子崩出来的)。
至于怎么查看 QChart 类的继承关系,使用Ctrl + Shift + T ,点击要查询的类的继承关系。
要想在项目里使用 Qt Charts 模块,需要在 pro 文件下添加以下语句。
QT += charts
如果我们点击查看 Qt Charts 类,我们可以看到要想使用 Qt Charts 类,除了需要包括相应 的头文件外,还需要使用命名空间,格式如下。
QT_CHARTS_USE_NAMESPACE
或者在头文件类外加上以下语句。
using namespace QtCharts;
下面我们直接开始例子,了解一下 Qt Charts 的使用。
应用实例
本例目的:快速了解 Qt Charts 的使用。例子非常实用,除了可以绘制静态曲线,也可以绘 制动态曲线。例子可以直接应用到实际项目中利用提供接口读取数据绘制动态曲线图。
项目名称:qtchart_test,实时动态曲线。基本流程如下:使用一个 QSplineSeries 对象(曲线),一个QChart(图表),一个 QChartView(图表视 图)。首先我们创建 chart 图表,然后创建两条坐标轴 axisX 与 axisY。将两条坐标轴添加到 chart 图表上,再将 splineSeries 曲线与坐标轴连系起来。最后再将 chart 图表添加到 chartView 图表视图中。曲线上的数据由系统产生随机数,使用定时器更新数据。
项目文件 qtchart_test.pro 文件第一行添加的代码部分如下。
QT += core gui charts
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += 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.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
在头文件“mainwindow.h”具体代码如下。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QChartView>
#include <QSplineSeries>
#include <QScatterSeries>
#include <QDebug>
#include <QValueAxis>
#include <QTimer>
#include <QMainWindow>
/* 必需添加命名空间 */
QT_CHARTS_USE_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
/* 接收数据接口 */
void receivedData(int);
/* 数据最大个数 */
int maxSize;
/* x轴上的最大值 */
int maxX;
/* y轴上的最大值 */
int maxY;
/* y轴 */
QValueAxis *axisY;
/* x轴 */
QValueAxis *axisX;
/* QList int类型容器 */
QList<int> data;
/* QSplineSeries对象(曲线)*/
QSplineSeries *splineSeries;
/* QChart图表 */
QChart *chart;
/* 图表视图 */
QChartView *chartView;
/* 定时器 */
QTimer *timer;
private slots:
void timerTimeOut();
};
#endif // MAINWINDOW_H
在源文件“mainwindow.cpp”具体代码如下。
#include "mainwindow.h"
#include <QDateTime>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
/* 设置最显示位置与大小 */
this->setGeometry(0, 0, 800, 480);
/* 最大储存maxSize - 1个数据 */
maxSize = 51;
/* x轴上的最大值 */
maxX = 5000;
/* y轴最大值 */
maxY = 40;
/* splineSeries曲线实例化(折线用QLineSeries) */
splineSeries = new QSplineSeries();
/* 图表实例化 */
chart = new QChart();
/* 图表视图实例化 */
chartView = new QChartView();
/* 坐标轴 */
axisY = new QValueAxis();
axisX = new QValueAxis();
/* 定时器 */
timer = new QTimer(this);
/* legend译图例类型,以绘图的颜色区分,本例设置为隐藏 */
chart->legend()->hide();
/* chart设置标题 */
chart->setTitle("实时动态曲线示例");
/* 添加一条曲线splineSeries */
chart->addSeries(splineSeries);
/* 设置显示格式 */
axisY->setLabelFormat("%i");
/* y轴标题 */
axisY->setTitleText("温度/℃");
/* y轴标题位置(设置坐标轴的方向) */
chart->addAxis(axisY, Qt::AlignLeft);
/* 设置y轴范围 */
axisY->setRange(0, maxY);
/* 将splineSeries附加于y轴上 */
splineSeries->attachAxis(axisY);
/* 设置显示格式 */
axisX->setLabelFormat("%i");
/* x轴标题 */
axisX->setTitleText("时间/ms");
/* x轴标题位置(设置坐标轴的方向) */
chart->addAxis(axisX, Qt::AlignBottom);
/* 设置x轴范围 */
axisX->setRange(0, maxX);
/* 将splineSeries附加于x轴上 */
splineSeries->attachAxis(axisX);
/* 将图表的内容设置在图表视图上 */
chartView->setChart(chart);
/* 设置抗锯齿 */
chartView->setRenderHint(QPainter::Antialiasing);
/* 设置为图表视图为中心部件 */
setCentralWidget(chartView);
/* 定时200ms */
timer->start(200);
/* 信号槽连接 */
connect(timer, SIGNAL(timeout()), this, SLOT(timerTimeOut()));
/* 设置随机种子,随机数初始化 */
qsrand(time(NULL));
}
MainWindow::~MainWindow()
{
}
void MainWindow::timerTimeOut()
{
/* 产生随机0~maxY之间的数据 */
receivedData(qrand() % maxY );
}
void MainWindow::receivedData(int value)
{
/* 将数据添加到data中 */
data.append(value);
/* 当储存数据的个数大于最大值时,把第一个数据删除 */
while (data.size() > maxSize) {
/* 移除data中第一个数据 */
data.removeFirst();
}
/* 先清空 */
splineSeries->clear();
/* 计算x轴上的点与点之间显示的间距 */
int xSpace = maxX / (maxSize - 1);
/* 添加点,xSpace * i 表示第i个点的x轴的位置 */
for (int i = 0; i < data.size(); ++i) {
splineSeries->append(xSpace * i, data.at(i));
}
}
receivedData(int value)函数是实现曲线移动的代码,代码算法是,当数据的个数超过最大值后, 我们就删除第一个数据,如此反复,就实现了数据移动的过程,同时图表视图中的曲线因为值的改变实现了“移动”。