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加速有較多的限制,只有自己權衡了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM