欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-25 16:24:06
在前面的博文中具体介绍了qchart组件是如何绘制各种通用的二维图形的,本章内容将继续延申一个新的知识点,通过数据库存储某一段时间节点数据的走向,当用户通过编辑框提交查询记录时,程序自动过滤出该时间节...

在前面的博文中具体介绍了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 的资料请关注其它相关文章!