QT Creator上位机画波形之Qcharts使用学习

先看一个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_NAMESPACE

int 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_NAMESPACE

QT_BEGIN_NAMESPACE
namespace Ui {
    
     class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    
    
    Q_OBJECT

public:
    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);
    //初始化QChart

    initChart();

    //设置timer
    timer = 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::AlignTop
    chart->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进入帮助文档查看

猜你喜欢

转载自blog.csdn.net/weixin_44788542/article/details/131314625