本文主要讲解如何动态绘制曲线图,并处理会遇到的一些问题,让程序能稳定持续运行
经过在网上的查询,发现大部分 都是推荐使用 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_NAMESPACE
QT_CHARTS_BEGIN_NAMESPACE
class QChartView;
class QChart;
QT_CHARTS_END_NAMESPACE
typedef QPair<QPointF, QString> Data;
typedef QList<Data> DataList;
typedef QList<DataList> DataTable;
QT_CHARTS_USE_NAMESPACE
class 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 combobox
m_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