当前位置: 代码迷 >> 综合 >> qt widgets chartview曲线图绘制(解决动态刷新内存过大问题)
  详细解决方案

qt widgets chartview曲线图绘制(解决动态刷新内存过大问题)

热度:87   发布时间:2023-11-20 06:35:23.0

本文主要讲解如何动态绘制曲线图,并处理会遇到的一些问题,让程序能稳定持续运行

经过在网上的查询,发现大部分 都是推荐使用 replace用法,因为append的用法随着时间会出现一些问题,我就将这两种方法分享一下各自的效果和使用心得。

1.replace

根据单词的意思就能知道这个函数的作用,意思就是替换,使用这个函数就不在适用scroll偏移效果了,就在一个曲线表,行和列是某一定值,然后刷新曲线就用replace将x轴新的点替换旧的点, 就可以实现图形的 更新了

代码部分:

.h

#ifndef THEMEWIDGET_H
#define THEMEWIDGET_H#include <QtWidgets/QWidget>
#include <QtCharts/QChartGlobal>
#include <QTime>
#include <QTimer>QT_BEGIN_NAMESPACE
class QComboBox;
class QCheckBox;
class Ui_ThemeWidgetForm;
QT_END_NAMESPACEQT_CHARTS_BEGIN_NAMESPACE
class QChartView;
class QChart;
QT_CHARTS_END_NAMESPACEtypedef QPair<QPointF, QString> Data;
typedef QList<Data> DataList;
typedef QList<DataList> DataTable;QT_CHARTS_USE_NAMESPACEclass ThemeWidget: public QWidget
{Q_OBJECT
public:explicit ThemeWidget(QWidget *parent = 0);~ThemeWidget();private Q_SLOTS:void updateUI();private:void populateThemeBox();void populateAnimationBox();void populateLegendBox();void connectSignals();QChart *createLineChart() const;
private slots:void timeSlot();
private:int m_valueMax;int m_valueCount;QList<QChartView *> m_charts;//DataTable m_dataTable;QChartView *chartView;QTimer *timer;Ui_ThemeWidgetForm *m_ui;};#endif /* THEMEWIDGET_H */

.cpp

#include "themewidget.h"
#include "ui_themewidget.h"QLineSeries *series;
QValueAxis *axisX;
QChart *chart;QString aaa;
QString ids;
unsigned long num=100;
int chardate[256];
int nowdate[256];
int lastdate[256];
static int rxnum=0,currectnum=0;
ThemeWidget::ThemeWidget(QWidget *parent) :QWidget(parent),m_ui(new Ui_ThemeWidgetForm)
{m_ui->setupUi(this);//初始化表格配置m_valueMax=255;m_valueCount=255;populateThemeBox();chartView = new QChartView(createLineChart());QGridLayout *baseLayout = new QGridLayout(); //便于显示,创建网格布局baseLayout->addWidget(chartView, 0, 0);// m_ui->gridLayout->addWidget(chartView, 1 , 1);m_ui->gridLayout->addLayout(baseLayout,1,1);chartView->setRenderHint(QPainter::Antialiasing);m_charts << chartView;//设置初始表格颜色QPalette pal = qApp->palette();pal.setColor(QPalette::Window, QRgb(0xf0f0f0));pal.setColor(QPalette::WindowText, QRgb(0x404044));qApp->setPalette(pal);//创建定时器timer = new QTimer(this);connect(timer, SIGNAL(timeout()), this, SLOT(timeSlot()));//绑定定时函数timer->start(20);}void ThemeWidget::timeSlot()
{for(int i=0;i<256;i++){nowdate[i]=qrang()%1000*0.15;//提供一个随机数// qDebug()<<nowdate[i];}for(int i=0;i<256;i++){series->replace(i,lastdate[i],i,nowdate[i]);//采用replace方式,比append串行方式节省内存,不会造成长时间运行电脑严重卡顿或者程序崩溃问题lastdate[i]=nowdate[i];//新数据使用完保存到旧数据数组里,下次replace用}}ThemeWidget::~ThemeWidget()
{delete m_ui;
}
//初始化chart配置
QChart *ThemeWidget::createLineChart() const
{chart = new QChart();chart->setTitle("UDP数据曲线图");QString name("UDP Data");series = new QLineSeries();series->setName(name);for(int i=0;i<256;i++){//初始化图形数值nowdate[i]=0;series->append(i,nowdate[i]);lastdate[i]=nowdate[i];//记录初始化的y值}chart->addSeries(series);chart->createDefaultAxes();chart->axisX()->setRange(0, m_valueMax);//chart->axisY()->setRange(-m_valueCount, m_valueCount); //设置y轴坐标有正负,但数据未说明有负值chart->axisY()->setRange(0, m_valueCount);//这里设置y轴坐标 只有正值axisX=new QValueAxis;//append要按照大小顺序依次添加axisX->setTickCount(5);//设置背景表格有5列chart->setAxisX(axisX,series);return chart;
}
//下拉模式选择
void ThemeWidget::populateThemeBox()
{// add items to theme comboboxm_ui->themeComboBox->addItem("Light", QChart::ChartThemeLight);m_ui->themeComboBox->addItem("Blue Cerulean", QChart::ChartThemeBlueCerulean);m_ui->themeComboBox->addItem("Dark", QChart::ChartThemeDark);m_ui->themeComboBox->addItem("Brown Sand", QChart::ChartThemeBrownSand);m_ui->themeComboBox->addItem("Blue NCS", QChart::ChartThemeBlueNcs);m_ui->themeComboBox->addItem("High Contrast", QChart::ChartThemeHighContrast);m_ui->themeComboBox->addItem("Blue Icy", QChart::ChartThemeBlueIcy);m_ui->themeComboBox->addItem("Qt", QChart::ChartThemeQt);
}
void ThemeWidget::updateUI()
{//设置主题颜色QChart::ChartTheme theme = static_cast<QChart::ChartTheme>(m_ui->themeComboBox->itemData(m_ui->themeComboBox->currentIndex()).toInt());const auto charts = m_charts;if (!m_charts.isEmpty() && m_charts.at(0)->chart()->theme() != theme){for (QChartView *chartView : charts) {chartView->chart()->setTheme(theme);}// Set palette colors based on selected theme//![8]QPalette pal = window()->palette();if (theme == QChart::ChartThemeLight) {pal.setColor(QPalette::Window, QRgb(0xf0f0f0));pal.setColor(QPalette::WindowText, QRgb(0x404044));//![8]} else if (theme == QChart::ChartThemeDark) {pal.setColor(QPalette::Window, QRgb(0x121218));pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));} else if (theme == QChart::ChartThemeBlueCerulean) {pal.setColor(QPalette::Window, QRgb(0x40434a));pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));} else if (theme == QChart::ChartThemeBrownSand) {pal.setColor(QPalette::Window, QRgb(0x9e8965));pal.setColor(QPalette::WindowText, QRgb(0x404044));} else if (theme == QChart::ChartThemeBlueNcs) {pal.setColor(QPalette::Window, QRgb(0x018bba));pal.setColor(QPalette::WindowText, QRgb(0x404044));} else if (theme == QChart::ChartThemeHighContrast) {pal.setColor(QPalette::Window, QRgb(0xffab03));pal.setColor(QPalette::WindowText, QRgb(0x181818));} else if (theme == QChart::ChartThemeBlueIcy) {pal.setColor(QPalette::Window, QRgb(0xcee7f0));pal.setColor(QPalette::WindowText, QRgb(0x404044));} else {pal.setColor(QPalette::Window, QRgb(0xf0f0f0));pal.setColor(QPalette::WindowText, QRgb(0x404044));}window()->setPalette(pal);}
}

通过以上代码就可以实现chart动态更新显示,把每次随机生成的点使用完时候保存到数组中,然后在下一次更新图像的时候replace就可以找到坐标对应的旧点,再用新的点去替换,就没有问题啦。

    void replace(qreal oldX, qreal oldY, qreal newX, qreal newY);void replace(const QPointF &oldPoint, const QPointF &newPoint);void replace(int index, qreal newX, qreal newY);void replace(int index, const QPointF &newPoint);

这里replace采用的是第一种方式。


2.append