服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C/C++ Qt 数据库与Chart历史数据展示

C/C++ Qt 数据库与Chart历史数据展示

2022-07-08 09:49LyShark C/C++

这篇文章主要介绍了Qt利用Qchart组件展示数据库中的历史数据。文中的示例代码讲解清晰,具有一定的学习和工作价值,感兴趣的小伙伴可以学习一下

本章通过数据库存储某一段时间节点数据的走向,当用户通过编辑框提交查询记录时,程序自动过滤出该时间节点下所有的数据,并将该数据动态绘制到图形组件内,实现动态查询图形的功能。

首先通过如下代码,创建Times表,表内记录有某个主机某个时间节点下的数值:

#include <QCoreApplication>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlRecord>
#include <iostream>
#include <QStringList>
#include <QString>
#include <QVariant>
#include <QDebug>
#include <QDateTime>
#include <QTime>

// 初始化数据库
// https://www.cnblogs.com/lyshark
void InitSql()
{
  QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");

  db.setDatabaseName("lyshark.db");
  if (!db.open())
  {
         std::cout << db.lastError().text().toStdString()<< std::endl;
         return;
  }

 // 执行SQL创建表
 db.exec("DROP TABLE Times");
 db.exec("CREATE TABLE Times ("
                 "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                 "address VARCHAR(64) NOT NULL, "
                 "datetime VARCHAR(128) NOT NULL, "
                 "value INTEGER NOT NULL"
         ")"
      );

 db.commit();
 db.close();
}

int main(int argc, char *argv[])
{
  QCoreApplication a(argc, argv);
  InitSql();
  return a.exec();
}

数据库结构如下:

C/C++ Qt 数据库与Chart历史数据展示

接着编写一个模拟插入数据的案例,该案例每一秒向数据库内插入一条记录,我们运行一段时间。

#include <QCoreApplication>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlRecord>
#include <iostream>
#include <QStringList>
#include <QString>
#include <QVariant>
#include <QDebug>
#include <QDateTime>
#include <QTime>

// 延时函数
void Sleep(int msec)
{
  QTime dieTime = QTime::currentTime().addMSecs(msec);
  while(QTime::currentTime() < dieTime)
      QCoreApplication::processEvents(QEventLoop::AllEvents,100);
}
// 生成随机数
int GetRandom()
{
  int num = qrand() % 100;
  return num;
}

// 插入数据
void InsertSQL()
{
  QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
  db.setDatabaseName("lyshark.db");
   if (!db.open())
   {
          std::cout << db.lastError().text().toStdString()<< std::endl;
          return;
   }

   for(int index=0;index <99999;index++)
   {
      QString address = QString("192.168.1.100");
      QDateTime curDateTime = QDateTime::currentDateTime();
      QString date_time = curDateTime.toString("yyyy-MM-dd hh:mm:ss");
      int value = GetRandom();

      QString run_sql = QString("INSERT INTO Times(id,address,datetime,value) VALUES (%1,'%2','%3',%4);")
                                .arg(index).arg(address).arg(date_time).arg(value);
      std::cout << "执行插入语句: " << run_sql.toStdString() << std::endl;

      db.exec(run_sql);
      db.commit();
      Sleep(1000);
   }
   db.close();
}

int main(int argc, char *argv[])
{
  QCoreApplication a(argc, argv);
  qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
  InsertSQL();
  return a.exec();
}

运行插入程序,统计一段时间 从 2021-12-11 15:34:16 到 2021-12-11 15:40:04 停止,表内记录如下:

C/C++ Qt 数据库与Chart历史数据展示

如果我们需要查询某一个时间节点下的数据,例如查询2021-12-11 15:35:00 - 2021-12-11 15:37:00的数据可以这样写SQL:

#include <QCoreApplication>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlRecord>
#include <iostream>
#include <QStringList>
#include <QString>
#include <QVariant>
#include <QDebug>
#include <QDateTime>
#include <QTime>

// 输出数据
// https://www.cnblogs.com/lyshark
void SelectSQL()
{
  QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
  db.setDatabaseName("lyshark.db");
   if (!db.open())
   {
          std::cout << db.lastError().text().toStdString()<< std::endl;
          return;
   }

  // 查询数据
  QSqlQuery query("SELECT * FROM Times;",db);
  QSqlRecord rec = query.record();

  // 循环所有记录
  while(query.next())
  {
      // 判断当前记录是否有效
      if(query.isValid())
      {
          int id_value = query.value(rec.indexOf("id")).toInt();
          QString address_value = query.value(rec.indexOf("address")).toString();
          QString date_time = query.value(rec.indexOf("datetime")).toString();
          int this_value = query.value(rec.indexOf("value")).toInt();

          if(date_time.toStdString() >= "2021-12-11 15:35:00" && date_time.toStdString() <="2021-12-11 15:37:00")
          {
              std::cout << "value: " << this_value << std::endl;
          }
      }
  }
}

int main(int argc, char *argv[])
{
  QCoreApplication a(argc, argv);
  SelectSQL();
  return a.exec();
}

这样就可以将该区间内所有的数据全部过滤出来了:

C/C++ Qt 数据库与Chart历史数据展示

将过滤参数与QChart组件结合即可实现动态绘图效果,绘制UI界面如下:

C/C++ Qt 数据库与Chart历史数据展示

当用户点击查询时,直接从数据库内取出数据,并将其动态更新到Chart组件内即可,实现代码如下:

#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlRecord>
#include <iostream>
#include <QStringList>
#include <QString>
#include <QVariant>
#include <QDebug>
#include <QDateTime>
#include <QTime>

// 初始化Chart图表
void MainWindow::InitChart()
{
  // 创建图表的各个部件
  QChart *chart = new QChart();

  // 将Chart添加到ChartView
  ui->graphicsView->setChart(chart);
  ui->graphicsView->setRenderHint(QPainter::Antialiasing);

  // 隐藏图例
  chart->legend()->hide();

  // 设置图表主题色
  ui->graphicsView->chart()->setTheme(QChart::ChartTheme(1));

  // 创建曲线序列
  QLineSeries *series0 = new QLineSeries();

  // 序列添加到图表
  chart->addSeries(series0);

  // 创建坐标轴
  QValueAxis *axisX = new QValueAxis;    // X轴
  axisX->setRange(1, 100);               // 设置坐标轴范围
  axisX->setLabelFormat("%d %");         // 设置X轴格式
  axisX->setMinorTickCount(5);           // 设置X轴刻度

  QValueAxis *axisY = new QValueAxis;    // Y轴
  axisY->setRange(0, 100);               // Y轴范围
  axisY->setMinorTickCount(4);           // s设置Y轴刻度

  // 设置X于Y轴数据集
  chart->setAxisX(axisX, series0);   // 为序列设置坐标轴
  chart->setAxisY(axisY, series0);
}

// 为序列生成数据
void MainWindow::SetData()
{
  // 获取指针
  QLineSeries *series0=(QLineSeries *)ui->graphicsView->chart()->series().at(0);

  // 清空图例
  series0->clear();

  // 链接数据库
  QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
  db.setDatabaseName("lyshark.db");
  if (!db.open())
  {
      return;
  }

  // 查询数据
  QSqlQuery query("SELECT * FROM Times;",db);
  QSqlRecord rec = query.record();

  // 赋予数据
  qreal t=0,intv=1;

  // 循环所有记录
  while(query.next())
  {
      // 判断当前记录是否有效
      // https://www.cnblogs.com/lyshark
      if(query.isValid())
      {
          QString address_value = query.value(rec.indexOf("address")).toString();
          QString date_time = query.value(rec.indexOf("datetime")).toString();
          int this_value = query.value(rec.indexOf("value")).toInt();

          // 获取组件字符串
          QString start_user_time = ui->dateTimeEdit_Start->text();
          QString end_user_time = ui->dateTimeEdit_End->text();

          // 将时间字符串转为秒,并计算差值 (秒为单位)
          QDateTime start_timet = QDateTime::fromString(start_user_time, "yyyy-MM-dd hh:mm:ss");
          QDateTime end_timet = QDateTime::fromString(end_user_time, "yyyy-MM-dd hh:mm:ss");

          uint stime = start_timet.toTime_t();
          uint etime = end_timet.toTime_t();

          // 只允许查询小于180秒的记录
          uint sub_time = etime - stime;
          if(sub_time <= 180)
          {
              // 查询指定区间内的数据
              if(date_time.toStdString() >= start_user_time.toStdString() && date_time.toStdString() <= end_user_time.toStdString())
              {
                  // std::cout << "区间内的数据: " << this_value << std::endl;
                  series0->append(t,this_value);
                  t+=intv;
              }
          }
          else
          {
              std::cout << "查询范围超出定义." << std::endl;
              return;
          }
      }
  }
}

// 将添加的widget控件件提升为QChartView类
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
  ui->setupUi(this);
  InitChart();

  // 初始化时间组件
  QDateTime curDateTime = QDateTime::currentDateTime();

  // 设置当前时间
  ui->dateTimeEdit_Start->setDateTime(curDateTime);
  ui->dateTimeEdit_End->setDateTime(curDateTime);

  // 设置时间格式
  ui->dateTimeEdit_Start->setDisplayFormat("yyyy-MM-dd hh:mm:ss");
  ui->dateTimeEdit_End->setDisplayFormat("yyyy-MM-dd hh:mm:ss");
}

MainWindow::~MainWindow()
{
  delete ui;
}

void MainWindow::on_pushButton_clicked()
{
  SetData();
}

查询效果如下所示:

C/C++ Qt 数据库与Chart历史数据展示

以上就是C/C++ Qt 数据库与Chart历史数据展示的详细内容,更多关于C++ Qt 的资料请关注服务器之家其它相关文章!

原文链接:https://www.cnblogs.com/LyShark/p/15675743.html

延伸 · 阅读

精彩推荐
  • C/C++C语言中qsort函数用法实例小结

    C语言中qsort函数用法实例小结

    这篇文章主要介绍了C语言中qsort函数用法,包括了针对各种数据类型参数的排序,非常具有实用价值,需要的朋友可以参考下...

    C语言程序设计8022021-02-01
  • C/C++opencv实现轮廓高斯滤波平滑

    opencv实现轮廓高斯滤波平滑

    这篇文章主要为大家详细介绍了opencv实现轮廓高斯滤波平滑,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    BHY_8192021-09-16
  • C/C++C++编写LINUX守护进程的实现代码

    C++编写LINUX守护进程的实现代码

    这篇文章主要介绍了如何使用C++实现LINUX守护进程,文中代码非常详细,供大家学习参考,感兴趣的小伙伴可以了解下...

    晟夏的叶11002021-09-09
  • C/C++C++实现KDTree 附完整代码

    C++实现KDTree 附完整代码

    这篇文章主要介绍了C++实现KDTree的代码详解,包括kdTree概念介绍及分割的作用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参...

    xiuzhublog7462021-11-25
  • C/C++C++中MFC Tab Control控件的使用详解

    C++中MFC Tab Control控件的使用详解

    这篇文章主要介绍了C++中MFC Tab Control控件的使用详解的相关资料,需要的朋友可以参考下...

    C++教程网11922021-02-27
  • C/C++C++非递归遍历磁盘文件和递归遍历磁盘文件的程序示例

    C++非递归遍历磁盘文件和递归遍历磁盘文件的程序示例

    这篇文章主要介绍了C++非递归遍历磁盘文件和递归遍历磁盘文件的程序示例,大家可以参考使用二种方法...

    C++教程网7462021-01-09
  • C/C++C语言:利用指针编写程序,用梯形法计算给定的定积分实例

    C语言:利用指针编写程序,用梯形法计算给定的定积分实例

    今天小编就为大家分享一篇C语言:利用指针编写程序,用梯形法计算给定的定积分实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看...

    Caleb_Sung10932021-08-10
  • C/C++C++实现简单计算器

    C++实现简单计算器

    这篇文章主要为大家详细介绍了C++实现简单计算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    时光丨荏苒9232021-09-06