Customplot画多条折线图,同时可以控制每条曲线的隐藏和显示

Customplot多条曲线的控制

前言

	开始使用Qcharts画图,大数据性能极差。于是转用Customplot画图,主要进行数据的实时更新和大量数据的加载

一、模拟数据

	采用子线程创建模拟数据,采用队列存储。
#pragma once#include 
#include
#include
#include
#include
#include
using namespace std;
class QTgui : public QThread
{Q_OBJECT
signals:void sigCurrentImage1(QVariant img);
public:QTgui(QObject *parent = nullptr);~QTgui();std::thread * tthread;void run();void SetRandNum();
private:int a;QString data;QMutex tex;QMap<QString, QQueue<QPointF>> datamap;//key 设备名称 value 点
};
#include "QTgui .h"
#include 
#include 
#include 
#include
#include
QTgui::QTgui(QObject *parent): QThread(parent)
{a = 0;
}QTgui ::~QTgui()
{}
void QTgui::run()
{qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));//point = new QQueue();// 要想线程一直运行 就用 while  不会运行一次就结束了while (1){SetRandNum();QVariant var;var.setValue(datamap);emit sigCurrentImage1(var);this_thread::sleep_for(std::chrono::milliseconds(1000));}}
void QTgui::SetRandNum()
{for (int i = 0; i < 1; i++){for (int j = 0; j < 3600; j++){QTime time(QTime::currentTime());int nowtime = time.msecsSinceStartOfDay();QPointF currentpoint = QPointF(nowtime, qrand() % 101);if (datamap.count(QString::number(i)) > 0){if (datamap[QString::number(i)].size() > 3600){datamap[QString::number(i)].dequeue();datamap[QString::number(i)].enqueue(currentpoint);}else{datamap[QString::number(i)].enqueue(currentpoint);}}else{QQueue<QPointF> dataqueue;dataqueue.enqueue(currentpoint);datamap.insert(QString::number(i), dataqueue);}}//QTime time(QTime::currentTime());//int nowtime = time.msecsSinceStartOfDay();//QPointF currentpoint = QPointF(nowtime, qrand() % 101);//if (datamap.count(QString::number(i)) > 0)//{//	if (datamap[QString::number(i)].size() > 1000000)//	{//		datamap[QString::number(i)].dequeue();//		datamap[QString::number(i)].enqueue(currentpoint);//	}//	else//	{//		datamap[QString::number(i)].enqueue(currentpoint);//	}//}//else//{//	QQueue dataqueue;//	dataqueue.enqueue(currentpoint);//	datamap.insert(QString::number(i), dataqueue);//}auto aa = 0;}}
数据有坐标点和时间点2种,测试注释掉了时间点。

二、主界面槽函数绑定

主要用于连接数据线程和UI槽函数的连接。

#pragma once
#include
#include 
#include "ui_QtWidgetsApplication7.h"
#include "QTgui .h"
#include
#include
class QtWidgetsApplication7 : public QMainWindow
{Q_OBJECT
public:QtWidgetsApplication7(QWidget *parent = Q_NULLPTR);void Init();~QtWidgetsApplication7();QTgui* g1;
signals:void SendData(QMap<QString, QQueue<QPointF>> data);//发送数据
private:Ui::QtWidgetsApplication7Class ui;int a = 1;
private slots:void slot2(QVariant data);
};
#include "QtWidgetsApplication7.h"
#include"qcustomplot.h"
#include"LineChartTest.h"
#if _MSC_VER >= 1600 //VS2015>VS>VS2010, MSVC VER= 10.0 -14.0 防止乱码
#pragma execution_character_set("utf-8")
#endif
QtWidgetsApplication7::QtWidgetsApplication7(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);Init();}
void QtWidgetsApplication7::Init()
{g1 = new QTgui(this);g1->start();connect(g1, SIGNAL(sigCurrentImage1(QVariant)), this, SLOT(slot2(QVariant)));LineChartTest *cht = new LineChartTest(this);connect(this, SIGNAL(SendData(QMap<QString, QQueue<QPointF>>)), cht, SLOT(ShowData(QMap<QString, QQueue<QPointF>>)));connect(this, SIGNAL(SendData(QMap<QString, QQueue<QPointF>>)), cht, SLOT(Run(QMap<QString, QQueue<QPointF>>)));QVBoxLayout *layout3 = new QVBoxLayout();layout3->addWidget(cht);ui.widget->setLayout(layout3);
}
QtWidgetsApplication7::~QtWidgetsApplication7()
{g1->terminate();//主动结束线程g1->deleteLater();
}void QtWidgetsApplication7::slot2(QVariant data)
{ui.label->setText(QString::number(a++));QMap<QString, QQueue<QPointF>> d=data.value<QMap<QString, QQueue<QPointF>>>();SendData(d);}

三、UI界面设置和显示

展示实时数据和更新界面。启用定时器更新界面。

#pragma once#include 
#include "QTgui .h"
#include "ui_LineChartTest.h"
#include "QCustomPlot.h"
using namespace std;
class LineChartTest : public QWidget
{Q_OBJECTpublic:LineChartTest(QWidget *parent = Q_NULLPTR);~LineChartTest();void initPlotForm();public slots:void ShowData(QMap<QString, QQueue<QPointF>> a);void Show_Plot();void Run(QMap<QString, QQueue<QPointF>> data);
private:Ui::LineChartTest ui;int data;void ShowChart();QCustomPlot *customPlot;QCPGraph *series[32];//最多可以设置曲线数量QQueue<QPointF> point;QTimer *timer;bool status;//显示哪条折线
};
#include "LineChartTest.h"
#include 
#include "QCustomPlot.h"
#pragma execution_character_set("utf-8")
LineChartTest::LineChartTest(QWidget *parent): QWidget(parent), status(false)
{ui.setupUi(this);initPlotForm();//定时器更新图表timer = new QTimer();timer->start(200);connect(timer, SIGNAL(timeout()), this, SLOT(Show_Plot()));QThread *thd = new QThread();customPlot->moveToThread(thd);//其他图像操作放到子线程thd->start();
}
void LineChartTest::ShowChart()
{}
LineChartTest::~LineChartTest()
{timer->deleteLater();
}
void LineChartTest::ShowData(QMap<QString, QQueue<QPointF>> getdata)
{}
//初始化图表格式
void LineChartTest::initPlotForm()
{//隐藏标题栏this->setWindowFlags(Qt::FramelessWindowHint);this->setWindowState((windowState()&~(Qt::WindowMinimized | Qt::WindowFullScreen)) | Qt::WindowMaximized);QVBoxLayout *layout = new QVBoxLayout();customPlot = new QCustomPlot(this);//QSharedPointer dateTicker(new QCPAxisTickerDateTime);//日期做X轴//dateTicker->setDateTimeFormat("m:s");//日期格式(可参考QDateTime::fromString()函数)//customPlot->xAxis->setTicker(dateTicker);//设置X轴为时间轴//customPlot->xAxis->setRange(0, 3601);customPlot->xAxis->ticker()->setTickCount(37);//11个主刻度customPlot->xAxis->setLabel("X轴");//轴标签customPlot->yAxis->setLabel("Y轴");//轴标签customPlot->yAxis->setRange(-30, 200);customPlot->xAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);//x轴终点箭头图案customPlot->xAxis->setLowerEnding(QCPLineEnding::esDisc);//x轴起点圆点图案customPlot->yAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);//x轴起点圆点图案layout->addWidget(customPlot);customPlot->setOpenGl(true);customPlot->addGraph(0)->setPen(QPen(Qt::red));// 允许用户用鼠标拖动轴范围,用鼠标滚轮缩放,点击选择图形:customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);ui.widget->setLayout(layout);
}
void LineChartTest::Run(QMap<QString, QQueue<QPointF>> data)
{int nowtime = QTime::currentTime().msecsSinceStartOfDay(); // 当前时间总的毫秒数customPlot->clearGraphs();  //请清除所有customPlot->xAxis->rescale(true);//调整X轴的范围,使之能显示出所有的曲线的X值customPlot->yAxis->rescale(true);//调整Y轴的范围,使之能显示出所有的曲线的Y值customPlot->xAxis->setRange(0, data["0"].size());//series->setObjectName("温度1");series[0]= customPlot->addGraph();series[0]->setName("温度1");series[0]->setPen(QPen(Qt::red));series[1] = customPlot->addGraph();series[1]->setName("湿度1");series[1]->setPen(QPen(Qt::blue));for (int i = 0; i < data[QString::number(0)].size(); i++){//给曲线添加数据//series->addData(data[QString::number(0)].at(i).x()*0.001, data[QString::number(0)].at(i).y());series[0]->addData(i, data[QString::number(0)].at(i).y());series[1]->addData(i, data[QString::number(0)].at(i).y()+50);}//this_thread::sleep_for(std::chrono::milliseconds(1));
}
//更新绘图 同时分别显示对应曲线
void LineChartTest::Show_Plot()
{if (status){for (int i = 0; i < 2; i++){if (series[i]->name() == "温度1"){series[i]->setVisible(false);}}status = !status;}else{for (int i = 0; i < 2; i++){if (series[i]->name() == "湿度1"){series[i]->setVisible(false);}}status = !status;}customPlot->replot(QCustomPlot::rpQueuedReplot);
}

效果展示

在这里插入图片描述
下载地址:https://download.csdn.net/download/qq_38491692/85311194

总结

	本文主要介绍了一个基本的绘制曲线的流程,线程产生数据,定时更新。解决界面卡顿问题。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部