开始使用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 > 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 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 > 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>)), cht, SLOT(ShowData(QMap>)));
connect(this, SIGNAL(SendData(QMap>)), cht, SLOT(Run(QMap>)));
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> d=data.value>>();
SendData(d);
}
三、UI界面设置和显示
展示实时数据和更新界面。启用定时器更新界面。
#pragma once #include#include "QTgui .h" #include "ui_LineChartTest.h" #include "QCustomPlot.h" using namespace std; class LineChartTest : public QWidget { Q_OBJECT public: LineChartTest(QWidget *parent = Q_NULLPTR); ~LineChartTest(); void initPlotForm(); public slots: void ShowData(QMap > a); void Show_Plot(); void Run(QMap > data); private: Ui::LineChartTest ui; int data; void ShowChart(); QCustomPlot *customPlot; QCPGraph *series[32];//最多可以设置曲线数量 QQueue 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 > 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 > 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
本文主要介绍了一个基本的绘制曲线的流程,线程产生数据,定时更新。解决界面卡顿问题。



