QtCharts模块勾画折线和曲线图

Posted ohsolong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QtCharts模块勾画折线和曲线图相关的知识,希望对你有一定的参考价值。

QtCharts画线图主要三个部分组成 QLIneSeries或QSplineSeries用于保存联系的坐标位置数据,QChart用于管理图像显示,例如图例,坐标主题等,QChartView则用于显示。

上代码

#ifndef WIDGET_H
#define WIDGET_H
#define SPLINE

#include <QWidget>
#include <QList>
#include <QTimerEvent>
#include <QtCharts/QLineSeries>
#include <QtCharts/QSplineSeries>
#include <QtCharts/QChart>
#include <QtCharts/QChartView>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

protected:
    void timerEvent(QTimerEvent *event);
private:
    void dataRefresh(QList<float> *t);
    Ui::Widget *ui;
    int _timerid;
    int _x = 20;
    int _y = 80;
    int _lineNumber = 10;
    QList<QList<float >*> *_data;
#ifndef SPLINE
    QList<QtCharts::QLineSeries*> *_lines;
#else
    QList<QtCharts::QSplineSeries*> *_splines;
#endif
    QtCharts::QChart * _chart;
    QtCharts::QChartView * _chartView;
    int count  = 0;
};
#endif // WIDGET_H

下面是cpp

#include "widget.h"
#include "./ui_widget.h"
#include <QDateTime>
#include <QtWidgets/QHBoxLayout>
#include <QtCharts/QValueAxis>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    _data = new QList<QList<float >*>();
#ifndef SPLINE
    _lines = new QList<QtCharts::QLineSeries*>();
#else
    _splines = new QList<QtCharts::QSplineSeries*>();
#endif
    _chart = new QtCharts::QChart();
    for(int i = 0; i< _lineNumber; i++)
    {
#ifndef SPLINE
        QtCharts::QLineSeries *s = new QtCharts::QLineSeries();
        connect(s, &QtCharts::QLineSeries::clicked,[](const QPointF& pointF){qDebug()<< pointF;});
        _lines->push_back(s);
#else
        QtCharts::QSplineSeries *s = new QtCharts::QSplineSeries();
        connect(s, &QtCharts::QSplineSeries::clicked,[](const QPointF& pointF){qDebug()<<pointF;});
        _splines->push_back(s);
#endif

        s->setPointLabelsClipping(false);
        s->setPointLabelsVisible(true);
        s->setPointsVisible(true);
        s->setPointLabelsFormat(QStringLiteral("(@xPoint,@yPoint)"));
        s->setName(QString::fromStdString("温度")+QString::number(i));
        //文档说明使用OpenGL加速可以更快的的勾画并且支持更多的点,但是会缺乏一些显示功能相对与CPU渲染
//        s->setUseOpenGL(true);
        qDebug()<<"OpenGL:"<<s->useOpenGL();
        _chart->addSeries(s);
    }
    _chart->setTitle(QString("曲线图"));
    QtCharts::QValueAxis *x = new QtCharts::QValueAxis();
    x->setRange(0, _x);
    x->setTitleText(QString::fromStdString("min"));
    x->setTickCount(30);
    QtCharts::QValueAxis  *y = new QtCharts::QValueAxis();
    y->setRange(0, _y);
    y->setTitleText(QString::fromStdString("摄氏度"));
    y->setTickCount(20);
    _chart->addAxis(x,Qt::AlignBottom);
    _chart->addAxis(y,Qt::AlignLeft);
    for(int i = 0; i< _lineNumber; i++){
#ifndef SPLINE
        (*_lines)[i]->attachAxis(x);
        (*_lines)[i]->attachAxis(y);
#else
        (*_splines)[i]->attachAxis(x);
        (*_splines)[i]->attachAxis(y);
#endif
    }

    _chart->legend()->show();
//    _chart->createDefaultAxes();
    _chartView = new QtCharts::QChartView(_chart);
    _chartView->setRenderHint(QPainter::Antialiasing);
//    _chartView->setRubberBand(QtCharts::QChartView::RectangleRubberBand);
    QHBoxLayout *h_layout = new QHBoxLayout();
    h_layout->addWidget(_chartView);
    setLayout(h_layout);
    _timerid = startTimer(1000);
    qsrand(QDateTime::currentDateTime().toTime_t());

}

Widget::~Widget()
{
    delete ui;
}
void Widget::timerEvent(QTimerEvent *event) {
    if(event->timerId() == _timerid)
    {
            QList<float > *v_list = new QList<float >();
            for (int i = 0; i < _lineNumber; i++) {
                float v = qrand() % _y;
                v_list->push_back(v);
            }
            dataRefresh(v_list);
        }
}

void Widget::dataRefresh(QList<float> *t) {
    if(_data->length() >= _x)
    {
        _data->clear();
#ifndef SPLINE
        for(int i=0; i < _lines->length();i++)
        {
            (*_lines)[i]->clear();
        }
#else
        for (int i = 0; i  < _splines->length(); ++i) {
            (*_splines)[i]->clear();
        }
#endif
    }
    _data->push_back(t);
    for (int i = 0; i < _lineNumber; ++i) {
        qDebug()<<_data->length()-1<<(*_data->last())[i];
#ifndef SPLINE
        (*_lines)[i]->append((_data->length()-1),(*_data->last())[i]);
#else
        (*_splines)[i]->append((_data->length()-1), (*_data->last())[i]);
#endif
    }
    qDebug()<< ++count;


}

本人是在ubuntu18.04平台 Qt版本5.12.6下进行的测试,用cmake进行的组织,使用了一个SPLINE宏进行了两个折线和曲线的切换。测试时发现series使用OpenGl渲染出现明显锯齿并且无法显示坐标点图标,所以本模所有功能块未对GPU渲染提供完全支持,官方文档也提供了提示。

技术图片

如过要使用OpenGL加速有较多的限制,只有自己权衡了。

以上是关于QtCharts模块勾画折线和曲线图的主要内容,如果未能解决你的问题,请参考以下文章

技术小新 | QtCharts快速入门

Canvas勾画二次曲线

MATLAB中将折线改为平滑曲线

如何用python画出折线图

彩色折线散点图python怎么指定数据

QT实现动态曲线