C/C++ Qt 資料庫與Chart歷史資料展示
阿新 • • 發佈:2021-12-11
在前面的博文中具體介紹了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(); }
資料庫結構如下:
接著編寫一個模擬插入資料的案例,該案例每一秒向資料庫內插入一條記錄,我們執行一段時間。
#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
停止,表內記錄如下:
如果我們需要查詢某一個時間節點下的資料,例如查詢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(); }
這樣就可以將該區間內所有的資料全部過濾出來了:
將過濾引數與QChart
元件結合即可實現動態繪圖效果,繪製UI介面如下:
當用戶點選查詢時,直接從資料庫內取出資料,並將其動態更新到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();
}
文章出處:https://www.cnblogs.com/lyshark版權宣告: 本部落格文章與程式碼均為學習時整理的筆記,部落格中除去明確標註有參考文獻的文章,其他文章 [均為原創] 作品,轉載請 [添加出處] ,您添加出處是我創作的動力!
本部落格所有文章除參考文獻特別宣告外,均採用 知識共享 署名-非商業性使用 [CC BY-NC-ND 4.0] 國際許可協議,請遵循協議許可
警告:如果您惡意轉載本人文章並被本人發現,則您的整站文章,將會變為我的原創作品,請相互尊重 !