Bootstrap

QT定时存储数据到数据库

之前的笔记里有写在qt中数据库如何使用,但是连接到数据库,表格创建成功,插入代码也编写完成,但是实际应用中你不可能每秒存储一次,频繁的数据库插入操作会增加CPU和I/O负担,软件肯定会比较卡顿。所以在使用Qt进行数据库操作时,确保优化数据插入频率以减少系统负荷是至关重要的。我们可以将数据先缓存起来,积累到一定数量再一起插入数据库。也可以设置定时器,每隔多长时间保存一次,间隔时间可以由用户在ui中自行选择。

目录

之前的笔记里有写在qt中数据库如何使用,但是连接到数据库,表格创建成功,插入代码也编写完成,但是实际应用中你不可能每秒存储一次,频繁的数据库插入操作会增加CPU和I/O负担,软件肯定会比较卡顿。所以在使用Qt进行数据库操作时,确保优化数据插入频率以减少系统负荷是至关重要的。我们可以将数据先缓存起来,积累到一定数量再一起插入数据库。也可以设置定时器,每隔多长时间保存一次,间隔时间可以由用户在ui中自行选择。

1.在需要保存数据的地方,发射保存数据信号

2.在主界面的构造函数中,连接保存数据信号与槽

3.在主界面中编写槽函数

4.在主界面构造函数中连接定时器与其对应的槽函数

5.编写定时器槽函数

6.ui界面中让用户自己选择存储的时间

7.编写点击设置按钮时触发的槽函数


1.在需要保存数据的地方,发射保存数据信号

 //处理存储在bms数据库中的数据
  processBmsData(addrArray,swapBcmuArray, swapBmuArray, swapHtemArray, bmsParamArray);
  emit signalBmsData();

2.在主界面的构造函数中,连接保存数据信号与槽

connect(this, &YF_bcmuInfo::signalBmsData, this, &YF_bcmuInfo::slotBmsData);

3.在主界面中编写槽函数

在此槽函数中,开启一个定时器,设置多久保存一次数据

每次触发这个槽函数,检测定时器是否开启,只有未开启的时候才打开定时器。

void YF_bcmuInfo::slotBmsData()
{     
    if (!sqlTimer->isActive()&& flagManualLock==false) {
        //表明已获取新数据,启动定时器,10s/30s/1min保存一次存储数据
        //flagManualLock是我设置的一个标志位,如果连接数据库失败打开数据库失败,设置这个标志位为true,当其为false就是打开成功的状态,当前这个标志位可以按需求选择是否使用。我这里如果不用,数据库打开成功还好,如果打开失败,定时器还会一直触发,就会一直去打开数据库。代码会卡死崩溃。
        sqlTimer->start();      
    }
}

,记得使用此定时器变量在主界面的构造函数中初始化,

//这个定时器用来决定几秒存一次数据到数据库中
    sqlTimer = new QTimer(this);
    sqlTimer->setInterval(10000);

4.在主界面构造函数中连接定时器与其对应的槽函数

connect(sqlTimer, &QTimer::timeout, this, &YF_bcmuInfo::slotSqlTimeOut);

5.编写定时器槽函数

void YF_bcmuInfo::slotSqlTimeOut()
{
   //获取之前存储的数据
    QVector<QString> bmsSqlData=getBmsData();
    QVector<QString> bmsParamSqlData = getBmsParamData();
    QVector<QString> bmsSqlDataEnd;
    for (int i = 2; i < bmsSqlData.size();++i) {
        bmsSqlDataEnd.append(bmsSqlData[i]);
    }

    //判断数据库是否打开
    bool bOk=false;
    if (!QDataBaseManager::getDataBase()->dbIsOpen())
    {
        bOk=QDataBaseManager::getDataBase()->open();
    }
    else {
        bOk = true;
    }
//数据库打开成功,创建表格,插入数据,创建表格是不存在才创建,存在不创建
    if (bOk) {
       
        if (bmsSqlData.size() >= 2) {
            QString basicDataTaName = "bcmu" + bmsSqlData[1] + "_" + "电池包" + bmsSqlData[0] + "_基础数据";
            QString paramDataTaName = "bcmu" + bmsSqlData[1] + "_" + "电池包" + bmsSqlData[0] + "_可读参数数据";
            QDataBaseManager::getDataBase()->createTable(basicDataTaName, bms_basic_header);
            QDataBaseManager::getDataBase()->createTable(paramDataTaName, bms_param_header);
            QDataBaseManager::getDataBase()->insertDataToTable(basicDataTaName, bmsSqlDataEnd);
            QDataBaseManager::getDataBase()->insertDataToTable(paramDataTaName, bmsParamSqlData);
            //bmsDb->exportTableToExcel();
        }

    }
//数据库没有打开,停止定时器,并设置标志位,否则代码会完全卡死,永远都会触发定时器进来判断是否打开
    else {
        qDebug() << "dataBase connect error";
        sqlTimer->stop();
        flagManualLock =true;
        return;
    }

}

6.ui界面中让用户自己选择存储的时间

7.编写点击设置按钮时触发的槽函数

void YF_bcmuInfo::on_btnSetInterval_clicked()
{
    int intervalNumber;
    //获取旁边combobox的当前文本
    QString interval = ui.cobBoxInterval->currentText();
    //得到后缀
    QString suffix=interval.right(1);
    //如果后缀是min
    if (suffix == "n") {
       //去掉后缀
        QString numberStr = interval.remove(interval.length() - 3, 3);
        // 将提取的数字部分转换为整数
        int number = numberStr.toInt(nullptr, 10);
        //将数据转为毫秒形式
         intervalNumber = number * 6 * 10000;
    }
    else {
       //如果是s,去掉后缀
        QString numberStr = interval.remove(interval.length() - 1, 1);
        // 将提取的数字部分转换为整数
        int number = numberStr.toInt(nullptr, 10);
        //转为毫秒形式
        intervalNumber = number * 1000;
    }
    //设置之前成员变量定时器的时间间隔
    sqlTimer->setInterval(intervalNumber);

}

;