先看一个Qcharts的简单demo
Qcharts是QT自带的组件,不需要另外添加文件。
打开QT Creator,新建一个工程,命名可以参考下图:
基类选择QWidget:
.pro文件中添加charts模块
main.cpp源码:
#include "widget.h"#include <QApplication>// 包含line chart需要的头文件
#include <QChartView>
#include <QLineSeries>// 引用命名空间
QT_CHARTS_USE_NAMESPACEint main(int argc, char *argv[])
{QApplication a(argc, argv);//绘制折线图采用的是QLineSeries序列类,两点间只是简单的用直线连接。QLineSeries *series = new QLineSeries();// 添加实验数据,可以用 append 方法 或者 << 操作符series->append(0,2);series->append(QPointF(2,6));series->append(3,8);series->append(7,9);series->append(11,3);*series << QPointF(11,2) << QPointF(15,5) << QPointF(18,4) << QPointF(19,2);QChart *chart = new QChart();// 将图例隐藏chart->legend()->hide();// 关联series,这一步很重要,必须要将series关联到QChart才能将数据渲染出来:chart->addSeries(series);// 开启OpenGL,QLineSeries支持GPU绘制,Qt其他有的图表类型是不支持的。series->setUseOpenGL(true);// 创建默认的坐标系(笛卡尔坐标)chart->createDefaultAxes();// 设置图表标题chart->setTitle(QStringLiteral("Qt line chart example"));QChartView *view = new QChartView(chart);// 开启抗锯齿,让显示效果更好view->setRenderHint(QPainter::Antialiasing);view->resize(400,300);// 显示图表view->show();return a.exec();
}
运行效果:
上面是一个折线图的示例。
QLineSeries类以折线图的形式显示数据。
折线图用于将信息显示为由直线连接的一系列数据点。
基本的创建折线的步骤如下:
// 逐一添加数据点
QLineSeries* series = new QLineSeries();
series->append(0, 6);
series->append(2, 4);
...
chart->addSeries(series);
先new一个QLineSeries,再逐一添加数据点,最后把实例化的QLineSeries与chart关联起来
我们可以把series单独看成一条图线,chart看成一个画布或坐标系,两个组合起来才是完整的图形。
注意append是逐一往后添加数据点,就是说存在添加的先后顺序。
上面的demo程序中出现了三个重要的class,分别是QLineSeries,QChart,QChartView
QChartView是一个独立的小部件,可以显示图表。
QLineSeries类以折线图的形式显示数据。折线图用于将信息显示为由直线连接的一系列数据点。
QChart类管理图表系列、图例和轴的图形表示。 为了简单地在布局中显示图表,可以使用类QChartView来代替QChart。
折线用QLineSeries,曲线用QSplineSeries
QSplineSeries是用来绘制光滑曲线的类,它在两点之间连线时采用插值算法(插值就是通过一系列已知的数据点,来"猜测"未知点),绘制折线图采用的是QLineSeries序列类,两点间只是简单的用直线连接。
上面的示例我们改一下
QLineSeries *series = new QLineSeries();
改成QSplineSeries *series = new QSplineSeries();
新增头文件#include <QSplineSeries>
运行效果:
动态刷新随机点
上节是直接在程序中用QChartView显示chart
这节看怎么在ui设计界面添加QChartView
找到Widget部件拉过去,调整好大小
添加的Widget控件不能显示chart图表,需要将其提升为QchartView。
具体操作:拖一个Widget控件到界面,右键Widget->提升为, 在提升的类名称一栏填:QChartView,头文件可以不管,会自动生成(如下图),然后点添加再点提升。
.pro文件中添加charts模块
widget.h文件中需要添加using namespace QtCharts;
或者QT_CHARTS_USE_NAMESPACE
都可以
widget.h文件源码:
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QtCharts/QSplineSeries>
#include <QtCharts>
#include <QDateTime>
using namespace QtCharts;
// 引用命名空间
//QT_CHARTS_USE_NAMESPACEQT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();//声明QChart的实例,QSplineSeries的实例QChart *chart; //画布QSplineSeries *series1; //线QDateTimeAxis *axisX; //轴QValueAxis *axisY;QTimer *timer; //计时器void drawLine();void initChart();
public slots://声明timer的槽函数void timerDeal();private:Ui::Widget *ui;
};
#endif // WIDGET_H
main.cpp维持默认
#include "widget.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}
widget.cpp源码:
#include "widget.h"
#include "ui_widget.h"
// 包含line chart需要的头文件
//#include <QChartView>
//#include <QLineSeries>
//#include <QSplineSeries>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//初始化QChartinitChart();//设置timertimer = new QTimer();//创建定时器timer->setInterval(400);//设置定时周期connect(timer,SIGNAL(timeout()),this,SLOT(timerDeal()));//连接定时器与定时溢出处理槽函数timer->start();}Widget::~Widget()
{delete ui;
}//实现QChart的初始化函数void Widget::initChart()
{chart = new QChart();//初始化QChart的实例series1 = new QSplineSeries();//初始化QSplineSeries的实例axisX = new QDateTimeAxis();//初始化X轴、Y轴axisY = new QValueAxis();//设置曲线的名称series1->setName("series1");chart->legend()->hide();//隐藏图例//把曲线添加到QChart的实例chart中chart->addSeries(series1);//设置X轴显示的范围axisX->setMin(QDateTime::currentDateTime().addSecs(-60*1));axisX->setMax(QDateTime::currentDateTime().addSecs(0));axisX->setFormat("hh:mm:ss"); //设置时间显示格式axisY->setMin(0); //设置Y轴范围axisY->setMax(10);//axisY->setRange(0,100); //也可以用这个设置范围//设置坐标轴上的格点axisX->setTickCount(5);axisY->setTickCount(10);//设置坐标轴显示的名称axisX->setTitleText("X轴");axisY->setTitleText("Y轴");//设置坐标轴的颜色,粗细,设置网格不显示axisY->setLinePenColor(QColor(Qt::darkBlue));axisY->setGridLineColor(QColor(Qt::darkBlue));axisY->setGridLineVisible(false);QPen penY1(Qt::darkBlue,3,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin);axisY->setLinePen(penY1);//把坐标轴添加到chart中,//addAxis函数的第二个参数是设置坐标轴的位置,//只有四个选项,下方:Qt::AlignBottom,左边:Qt::AlignLeft,右边:Qt::AlignRight,上方:Qt::AlignTopchart->addAxis(axisX,Qt::AlignBottom);chart->addAxis(axisY,Qt::AlignLeft);//把曲线关联到坐标轴series1->attachAxis(axisX);series1->attachAxis(axisY);//把chart显示到窗口上ui->widget->setChart(chart);ui->widget->setRenderHint(QPainter::Antialiasing); //设置抗锯齿
}//实现画线函数,动态更新
void Widget::drawLine()
{//每增加一个点改变X轴的范围,实现曲线的动态更新效果QDateTime bjtime=QDateTime::currentDateTime();chart->axisX()->setMin(QDateTime::currentDateTime().addSecs(-60*1));//系统当前时间的前一秒chart->axisX()->setMax(QDateTime::currentDateTime().addSecs(0));//系统当前时间//当曲线上最早的点超出X轴的范围时,剔除最早的点,
// if(series1->count()>119)
// {
// series1->removePoints(0,series1->count()-119);
// }qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));//设置种子int Y1=qrand()%9;//随机生成0到9的随机数//增加新的点到曲线末端series1->append(bjtime.toMSecsSinceEpoch(),Y1);
}//实现timer的槽函数
void Widget::timerDeal()
{//定时画曲线drawLine();
}
效果:
对上面的例程我们需要了解的:
1、代码中没有定义chart 的整个图占的大小,所以ui里添加的Widget控件可以直接通过拉动四个角调整大小。
比如下图,就是只在ui里调整了Widget控件使其高度缩小的效果
2、对比一下不开抗锯齿的情况:
即ui->widget->setRenderHint(QPainter::Antialiasing);
这句去掉
3、为了显示图表,除了Widget控件可以提升为QchartView,还有Graphics View组件也可以提升为QchartView(目前只测试了这两个可以提升QchartView,应该还有别的)
相关方法
QChart类方法
// 1.添加自定义坐标轴 Qt::AlignLeft 左侧X轴 Qt::AlignBottom 下端Y轴
void addAxis(QAbstractAxis *axis, Qt::Alignment alignment)
// 2.设置默认坐标轴(QChart为根据系列上的数据,创建合适的坐标轴,数据中最小/最大的x值为坐标的x的范围,数据中最小/最大的y值为坐标的y的范围)
void createDefaultAxes()
// 3.移除坐标轴
void removeAxis(QAbstractAxis *axis)
// 3.添加单个系列
void addSeries(QAbstractSeries *series)
// 4.移除单个系列
void QChart::removeSeries(QAbstractSeries *series)
// 5.移除全部系列
void QChart::removeAllSeries()
// 6.平移
void scroll(qreal dx, qreal dy)
// 7.设置外边距,通过设置负数可以是图表外面的空白减小 QMargins m(-10,-10,-10,-10);
void setMargins(const QMargins &margins)
// 8.设置图表绘制的位置,注意:不包含坐标轴 QRectF r(0,0,600,400); 此时将看不到Y轴坐标轴
void setPlotArea(const QRectF &rect)
// 9.设置标题
void setTitle(const QString &title)
// 9.1设置绘制标题的画刷
void setTitleBrush(const QBrush &brush)
// 9.2设置标题的字体
void setTitleFont(const QFont &font)
// 10.放大/缩小坐标轴的范围 以图表的中心点开始放大/缩小
void zoom(qreal factor)
// 11.获取图表的图例,即系列的名称 通过 QLegend.hide() 可隐藏图表中所有的图例
QLegend *QChart::legend() const
QValueAxis类方法
// 1 设置范围
void setRange(qreal min, qreal max)
void setMax(qreal max)
void setMin(qreal min)
// 2 设置网格划分类型 QValueAxis::TicksDynamic 按固定值划分 QValueAxis::TicksFixed 按份来划分(默认)
void setTickType(QValueAxis::TickType type);
// 3 设置主要刻线线 设置为11,则按范围等分为10份, 在 QValueAxis::TicksFixed 时生效
void setTickCount(int count)
// 4 设置次要刻线, 设置为6,即给每个主刻度线在等分为5份 共 10 * 5 50份 在 QValueAxis::TicksFixed 时生效
void setMinorTickCount(int count)
// 5 按值设置刻度线,每两条刻度线间隔的值为设置的值,在 QValueAxis::TicksDynamic 时生效
void setTickInterval(qreal insterval)
// 6 隐藏刻度线
void QAbstractAxis::hide()
// 7 设置主要刻度线的颜色
void setGridLineColor(const QColor &color)
// 8 设置主要刻度线的画笔
void setGridLinePen(const QPen &pen)
// 9 设置主要刻度线的可见性
void setGridLineVisible(bool visible = true)
// 10 设置轴线的颜色
void setLinePenColor(QColor color)
// 11 设置轴线的可见性
void setLineVisible(bool visible = true)
// 12 设置标题
void setTitleText(const QString &title)
void setTitleFont(const QFont &font)
void setShadesColor(QColor color)
void setShadesPen(const QPen &pen)
void setShadesBrush(const QBrush &brush)
void setTitleVisible(bool visible = true)
// 13 设置标签
void setLabelsAngle(int angle)
void setLabelsColor(QColor color)
void setLabelsFont(const QFont &font)
void setLabelFormat(const QString &format) // ("%d") %d为十进制显示
QAbstractSeries类下的QXYSeries方法
QAbstractSeries为系列的基类,其下又分为 QXYSeries类(折线图、样条曲线图、散点图的基类)、QPieSeries类(饼状图)、QAbstractBarSeries类(条状图)等
-QAbstractSeries
---QXYSeries
-----QLineSeries 折线图
-------QSplineSeries样条曲线图 // 相比较于QLineSeries,更加平滑,同时更加耗时,大概为2.5倍时间,不过总时间很小(10000个点0.3ms),基本可忽略
-----ScatterSeries 散点图
---QPieSeries
---QAbstractBarSeries 方法:
// 1.1 添加单个数据 不推荐
void append(qreal x, qreal y)
// 1.2 添加单个数据 不推荐
void append(const QPointF &point)
// 1.3 添加多个数据 不推荐
void append(const QList<QPointF> &points)
// 1.4 替换单个数据 不推荐
void replace(qreal oldX, qreal oldY, qreal newX, qreal newY)
// 1.5 替换多个数据 不推荐
void replace(QList<QPointF> points)
// ***1.6 替换多个数据 极力推荐 (使用replace时,将不需要使用clear())
void replace(QVector<QPointF> points)
// 2 在系列中根据索引获取坐标
const QPointF &at(int index) const
// 3 插入某个点
void insert(int index, const QPointF &point)
// 4 获取画刷
QBrush brush() const
// 5 清空
void clear()
// 6 获取颜色 折线图、样条曲线图的线条颜色 散点图的填充颜色
virtual QColor color() const
// 7 获取点的数量
int count() const
// 8 获取绘制轮廓的笔
QPen pen() const
// 9 获取所有点
QVector<QPointF> pointsVector() const
// 10 该系列点是否绘制(是否可见) 注意:设置为false时,看不见凸出的点,但是线仍然可以看见
bool pointsVisible() const
// 11 设置绘制点的画刷
virtual void setBrush(const QBrush &brush)
// 12 设置绘制点的笔
virtual void setPen(const QPen &pen)
// 13 设置绘制线的画刷 折线图、样条曲线图的线条颜色 散点图的填充颜色
virtual void setColor(const QColor &color)
// 14.1 设置点的标签,每个点都会被设置
void setPointLabelsFormat(const QString &format)
// 14.2 设置裁剪,超过图表区域部分会被裁剪
void setPointLabelsClipping(bool enabled = true)
// 14.3 设置点的标签的颜色
void setPointLabelsColor(const QColor &color)
// 14.4 设置点的标签的字体
void setPointLabelsFont(const QFont &font)
// 14.5 设置点的标签的可见
void setPointLabelsVisible(bool visible = true)
// 15 绑定坐标轴 需要连续绑定X轴、Y轴,而且要与QChart绑定同一组坐标轴
bool QAbstractSeries::attachAxis(QAbstractAxis *axis)
小提示:对于代码中不清楚的类或方法,都可以选定后按F1进入帮助文档查看