当前位置: 首页 > news >正文

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 columnQString 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添加到ChartViewui->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;}}}
}

这段代码实现了通过用户输入条件查询数据库,并动态更新折线图的功能,用于在界面上显示符合条件的数据趋势。

至此数据库与绘图组件的联动效果就实现了,其实很容易理解,因为是一个案例并没有包含任何复杂的功能这也是为了方便功能的展示,读者可自行运行并查询一个区间内的折线图,如下所示;

相关文章:

  • 北斗卫星助力智慧公园实现智能化管理
  • 基于Java+SpringBoot+vue+elementUI私人健身教练预约管理系统设计实现
  • 0111qt
  • 【Docker Compose】案例分享
  • maven的scop作用域依赖问题导致idea社区版报错
  • 【椒盐玉兔】GPTs Store 商店的TOP100 自定义GPT使用报告
  • 数据结构栈、队列、链表、散列表
  • js_BOMDomAjax
  • 联邦学习中聚合算法可能怎样创新,智慧农业结合什么数学理论或知名理论实现创新并发表文章
  • S7-200SMART实例之冒泡法排序子程序
  • 能赚钱的GPT Store正式上线!如何将自己的 GPT 放到商店中?
  • 红队打靶练习:BREACH: 1
  • 【计算机网络】TCP原理 | 可靠性机制分析(三)
  • PyCharm使用手册
  • vim常用命令总结
  • 收藏网友的 源程序下载网
  • 2017 前端面试准备 - 收藏集 - 掘金
  • CentOS 7 修改主机名
  • css选择器
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • PHP CLI应用的调试原理
  • Python进阶细节
  • RxJS: 简单入门
  • Spring Cloud Feign的两种使用姿势
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • WebSocket使用
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 记一次删除Git记录中的大文件的过程
  • 理清楚Vue的结构
  • 如何胜任知名企业的商业数据分析师?
  • 实战|智能家居行业移动应用性能分析
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • 【云吞铺子】性能抖动剖析(二)
  • 2017年360最后一道编程题
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • ![CDATA[ ]] 是什么东东
  • #include
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (1)(1.13) SiK无线电高级配置(五)
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (Git) gitignore基础使用
  • (Java)【深基9.例1】选举学生会
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • ***检测工具之RKHunter AIDE
  • ./configure,make,make install的作用(转)
  • .net/c# memcached 获取所有缓存键(keys)
  • .Net+SQL Server企业应用性能优化笔记4——精确查找瓶颈
  • .NET6 命令行启动及发布单个Exe文件