C++ Qt开发:Charts与数据库组件联动
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍Charts组件与QSql数据库组件的常用方法及灵活运用。
在之前的文章中详细介绍了关于QCharts绘图组件的使用方式,本章将继续延续这个知识点,通过使用QSql数据库模块动态的读取某一个时间节点上的数据,当用户点击查询数据时则动态的输出该事件节点的所有数据,并将数据绘制到图形组件内,实现动态查询图形的功能。
首先我们需要生成一些测试数据,在文章课件中有一个InitDatabase案例,该案例中通过QSql组件动态创建一个Times表,该表中有三个字段分别记录了主机IP地址、时间、以及数据,并动态的想表中插入一些随机测试数据,读者可运行这段程序并等待十分钟以上,此时数据库database.sqlite3中将会出现如下所示的数据集;

再来看下主窗体是如何设计的,左侧使用一个ComboBox下拉选择框,右侧使用两个可自由调节的Date/TimeEdit组件,最底部则是一个graphicsView绘图组件,如下图;

由于涉及到IP地址的选择,所以在MainWindow主构造函数中我们需要对ComboBox组件进行初始化,在初始化时我们需要打开数据库并将数据库中的Times表,并查询到address字段,这里在查询语句中使用DISTINCT语句,该语句是用于在SQL查询中选择唯一值的关键字,它能够确保查询的结果集中每个列的值都是唯一的。
SELECT DISTINCT address FROM Times;
在代码中,上述查询的目的是从 "Times" 表中选择唯一的 "address" 列的值。如果 "Times" 表中有多个行具有相同的 "address" 值,DISTINCT 会确保在结果中只返回一个该值,以避免重复。
当具备了这条语句那么查询唯一值将变得非常容易,当查询到对应值只有只需要通过comboBox->addItem即可将唯一的IP地址追加到组件中,如下代码所示;
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 初始化绘图
InitLineChart();
// 初始化时间组件
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");
// 初始化数据库
db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("database.sqlite3");
if (!db.open())
{
std::cout << db.lastError().text().toStdString() << std::endl;
return;
}
// 查询数据库中的IP地址信息
QSqlQuery query;
if (query.exec("SELECT DISTINCT address FROM Times;"))
{
QSet<QString> uniqueAddresses;
while (query.next())
{
// Assuming 'address' is the name of the column
QString data_name = query.value(0).toString();
uniqueAddresses.insert(data_name);
}
// 清空现有的项
ui->comboBox->clear();
// 将唯一地址添加到 QComboBox 中
foreach (const QString &uniqueAddress, uniqueAddresses)
{
ui->comboBox->addItem(uniqueAddress);
}
}
else
{
std::cout << query.lastError().text().toStdString() << std::endl;
}
}
接着来看下如何实现InitLineChart()绘图函数,绘图部分由于我们不需要直接绘制所以这里可以先初始化折线图表,等待后期添加数据绘制即可,这段代码的实现如下所示;
首先,创建一个QChart对象,代表整个图表,并将其添加到QGraphicsView中。随后,通过隐藏图例提高图表的美观度。接着,创建一个QLineSeries对象,表示折线图中的数据序列,并将其添加到图表中。为确保正确显示,创建了X轴和Y轴的坐标轴对象,并设置了范围、格式和刻度。最后,将X轴和Y轴与折线序列关联,以便在图表中显示数据。这段代码实现了一个简单的折线图的初始化,为进一步添加和展示数据提供了基础。
// 初始化Chart图表
void MainWindow::InitLineChart()
{
// 创建图表的各个部件
QChart *chart = new QChart();
// 将Chart添加到ChartView
ui->graphicsView_line->setChart(chart);
ui->graphicsView_line->setRenderHint(QPainter::Antialiasing);
// 隐藏图例
chart->legend()->hide();
// 创建曲线序列
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);
}
当界面中的按钮被点击后,事件触发时执行,其主要功能是从数据库中查询记录并根据用户在界面上选择的设备地址、起始时间和结束时间条件,筛选符合条件的数据,并将其显示在折线图中。
首先,获取折线图对象和数据库查询结果的指针,然后清空折线序列准备接收新的数据。通过遍历数据库查询结果,获取每条记录的字段值,同时获取用户输入的查询条件。计算时间差并限制查询范围在3600秒内,然后判断记录是否在指定的时间范围内,并将符合条件的数据点添加到折线序列中。如果查询范围超出定义,输出错误消息。
void MainWindow::on_pushButton_clicked()
{
// 获取指针
QLineSeries *series0=(QLineSeries *)ui->graphicsView_line->chart()->series().at(0);
// 清空图例
series0->clear();
// 查询数据
QSqlQuery query("SELECT * FROM Times;",db);
QSqlRecord rec = query.record();
// 赋予数据
qreal t=0,intv=1;
// 循环所有记录
while(query.next())
{
// 判断当前记录是否有效
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 address_user = ui->comboBox->currentText();
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();
// 只允许查询小于3600秒的记录
uint sub_time = etime - stime;
if(sub_time <= 3600)
{
// 查询指定区间内的数据
if(date_time.toStdString() >= start_user_time.toStdString() &&
date_time.toStdString() <= end_user_time.toStdString() &&
address_value == address_user
)
{
// std::cout << "区间内的数据: " << this_value << std::endl;
series0->append(t,this_value);
t+=intv;
}
}
else
{
std::cout << "查询范围超出定义." << std::endl;
return;
}
}
}
}
这段代码实现了通过用户输入条件查询数据库,并动态更新折线图的功能,用于在界面上显示符合条件的数据趋势。
至此数据库与绘图组件的联动效果就实现了,其实很容易理解,因为是一个案例并没有包含任何复杂的功能这也是为了方便功能的展示,读者可自行运行并查询一个区间内的折线图,如下所示;

C++ Qt开发:Charts与数据库组件联动的更多相关文章
- C/C++ Qt 数据库与TableView多组件联动
Qt 数据库组件与TableView组件实现联动,以下案例中实现了,当用户点击并选中TableView组件内的某一行时,我们通过该行中的name字段查询并将查询结果关联到ListView组件内,同时将 ...
- win使用MSYS2安装Qt开发环境
原文链接 MSYS2 下载地址: pacman的具体用法 有pacman的具体使用方法.我们首先对系统升级 我们首先对系统升级 pacman -Syu 就会检测整个系统可以升级的组件,并自动下载安装, ...
- 细数Qt开发的各种坑(欢迎围观)
1:Qt的版本多到你数都数不清,多到你开始怀疑人生.从4.6开始到5.8,从MSVC编译器到MINGW编译器,从32位到64位,从Windows到Linux到MAC.MSVC版本还必须安装对应的VS2 ...
- 基于QT开发的第三方库
基于Qt开发的第三方库 分类: Qt2014-02-12 11:34 1738人阅读 评论(0) 收藏 举报 QT第三方库 目录(?)[+] 文章来源:http://blog.csdn.net ...
- HubbleDotNet全文搜索数据库组件(一)
HubbleDotNet 简介及安装详解 2012-11-05 12:59 来源:9SSSD.COM 作者:starts_2000 字号:T|T [摘要]HubbleDotNet 是一个基于.net ...
- 【应用笔记】【AN005】Qt开发环境下基于RS485的4-20mA电流采集
简介 4-20mA电流环具有广泛的应用前景,在许多行业中都发挥着重要作用.本文主要介绍在Qt开发环境下基于RS485实现4-20mA电流采集,实现WINDOWS平台对数据的采集.分析及显示. 系统组成 ...
- Qt开发环境下载和安装
Qt是跨平台的图形开发库,目前由Digia全资子公司 Qt Company 独立运营,官方网址: http://www.qt.io/ 也可以访问Qt项目域名:http://qt-project.org ...
- QT基于model/view数据库编程2
Qt中数据编程主要分为以下两点:1.利用qt提供类 访问数据库或者成为简单的数据库编程2.数据库编程中引入model/view编程模型 基于model/view数据库编程: qt提供model类: Q ...
- Qt开发北斗定位系统融合百度地图API及Qt程序打包发布
Qt开发北斗定位系统融合百度地图API及Qt程序打包发布 1.上位机介绍 最近有个接了一个小型项目,内容很简单,就是解析北斗GPS的串口数据然后输出经纬度,但接过来觉得太简单,就发挥了主观能动性,增加 ...
- windows下VisualStudio和QtCreator搭建Qt开发环境
一.简介 集成开发平台IDE都有各自的长处,编写Qt程序可根据自己的喜好来选择相应的IDE.下述文章都是装载博友的文章,其中有很多细节还得自己调整. 二.详解 1.VisualStudio搭建Qt开发 ...
随机推荐
- .NET反编译神器ILSpy怎么用?
前言 上一篇文章我们介绍了4款免费且实用的.NET反编译工具,这篇文章主要来说说ILSpy这个工具该如何安装和使用. ILSpy ILSpy是一款免费.开源的 .NET 反编译工具,能够将已编译的 . ...
- python第6章code
01条件判断语句 # 条件判断语句(if语句)# 语法:if 条件表达式 : # 代码块# 执行的流程:if语句在执行时,会先对条件表达式进行求值判断,# 如果为True,则执行if后的语句# 如果为 ...
- ubuntu实时查看网速
可以使用ifstat这个命令 安装 apt install ifstat 1 使用,直接打命令就行 ifstat
- 如何通过代码混淆绕过苹果机审,解决APP被拒问题
目录 iOS代码混淆 功能分析 实现流程 类名修改 方法名修改 生成垃圾代码 替换png等静态资源MD5 info.plist文件添加垃圾字段 功能分析 实现流程 类名修改 方法名修改 生成垃圾代码 ...
- [ABC202E] Count Descendants 题解
Count Descendants 题目大意 给定一颗以 \(1\) 为根的树,多次询问求某点的子树中深度为给定值的点的个数. 思路分析 对于每个深度开一个 vector,从大到小存下这个深度的所有点 ...
- P9481 [NOI2023] 贸易 题解
题目链接 题目要求我们求出任意两点间最短路径之和,由于图比较特殊,除树边外只有祖先到其子树内的边,我们首先考虑最短路径有没有什么特殊性质. 注意到两点之间的最短路分为一下三种: 节点到其祖先的最短路: ...
- QT(5)-QHeaderView
@ 目录 1 说明 2 函数 2.1 级联调整大小 2.2 默认对齐方式 2.3 count() 2.4 表头默认单元格大小 2.5 hiddenSectionCount() 2.6 分区显示和隐藏 ...
- 编写高性能C#代码 —— Span<T>
Span 提供任意内存的连续区域的类型安全和内存安全表示形式.它是在堆栈而不是托管堆上分配的ref结构,是对任意内存块的抽象 . 1.关于Span 在NET Core 2.1中首次引入 提供对任意内存 ...
- Android Gson 混淆问题
开发过程中遇到一个奇怪的问题. 有一个接口,debug 版本接收到云侧下发的字符串后可以通过 gson 将其转换为相应 bean 类,而 release 版本拿到的 bean 总是缺少一个关键的字段, ...
- OpenAI宫斗,尘埃落定,微软成最大赢家
周末被OpenAI董事会闹剧刷屏,ChatGPT之父Sam Altman前一天被踢出董事会,免职CEO,后一天重返OpenAI,目前结局未知. 很多同学想要围观,缺少背景知识,这里老章为大家简单介绍前 ...