【C++ QT项目实战-03】---- C++ QT系统实现读取JSON文件数据的自动化模式

🎩 欢迎来到技术探索的奇幻世界👨‍💻

📜 个人主页@一伦明悦-CSDN博客

✍🏻 作者简介C++软件开发、Python机器学习爱好者

🗣️ 互动与支持💬评论      👍🏻点赞      📂收藏     👀关注+

如果文章有所帮助,欢迎留下您宝贵的评论!

欢迎点赞加收藏支持我,点击关注,一起进步!


前言      

        本篇在该篇博客的基础上,继续进行系统功能的完善操作,比如,一般生产国臣各种,跟定希望机器是能自动化的,这样即使工作人员不在,生产依然在进行。

【C++ QT项目实战-02】---- C++ QT系统实现基于QT调用RESTful接口访问JSON文件中数据-CSDN博客文章浏览阅读457次,点赞5次,收藏3次。本篇在做项目的基础上进行了项目中难点的一些总结,我们都知道,在如今大数据时代下,数据对项目系统开发起到决定性的作用,可以帮助企业实现实时决策、提升用户体验、实现业务智能、提高系统性能、提供定制化服务和增强业务竞争力等方面的优势,有利于项目系统的发展和成功。因此,在项目系统开发过程中,需要充分重视数据的快速读取和处理能力,以满足日益增长的数据需求和用户期望。https://blog.csdn.net/m0_59951855/article/details/139065776

        项目中的计算等功能已经是自动化模式的,这里的难题就是如何在读取数据的过程中也实现自动化模式,当然,为了便于操作,不仅需要自动化模式,也需要随时可以切换到手动模式。

        这里包含了以下几个难点:

        (1)主系统线程与计算线程是双线程运行,两种模式下,如何进行线程通信?

        (2)自动模式下,系统访问平台的方式,或者说是否需要给定时间,定时访问平台?而不是不停歇的访问。

        (3)自动模式下如何实现系统读完数据直接进行计算,手动模式下又怎样切换?这些也需要进行解决。

        (4)如何判断平台中是否存在数据,当判断之后,又该怎样运行?
        带着这四个问题,将进行详细分析如何实现这些功能,并给出代码解释和功能演示。

正文 

01- 双模式下,主线程与计算线程通信实现   

        主界面上的自动和手动两种模式通过控件进行选择,当选择自动模式时,主线程发送一个信号,通过信号与槽函数的方式与计算线程中的函数进行连接。

        在自动模式下,发送信号 send_cmBox_ToWFC,计算线程中使用函数cmBox_switch()和model_switch()来接收信号并实现各种功能。在手动模式下,发送信号 send_modelcmBox_ToWFC,计算线程中使用函数model_switch_0来接收信号。

这种设计模式可以让你在不同模式下灵活地控制计算线程的行为,实现自动化或手动化操作。

mainwindow.h文件#ifndef MAINWINDOW_H
#define MAINWINDOW_H
/*#include "Mp_Pred.h"*/
#include"ui_mainwindow.h"
#include <QMainWindow>
#include <QLabel>#include "spdlog/fmt/ostr.h"
#include "Zanj_WFC_ctrl.h"
#include <QVariant>
#include "wfc_to_main.h"#include <QtSql/QtSql>
#include <QDateTime>
#include <QTimer>
#include <qtextcodec.h> 
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtCharts/QChartView>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QLegend>
#include <QtCharts/QBarCategoryAxis>
#include <QMouseEvent>
//一定要声明!!!
#include"dialog_data_log.h"namespace Ui {class MainWindow;
}};
class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();Zanj_WFC_ctrl * m_Zanj_WFC_ctrl; // 预报计算的类QThread * m_Zanj_WFC_ctrl_Thread; //m_Mp_Pred将被移动到此线程执行void connectZanj_WFC_ctrl(Zanj_WFC_ctrl *m_Zanj_WFC_ctrl);signals:void send_cmBox_ToWFC();void send_modelcmBox_ToWFC();mainwindow.cpp文件#include  <QTimer>
#include  <time.h>
#include  <QLabel>
#include  <QValueAxis>
#include  <QMargins>
#include  <QtWidgets/QApplication>
#include  <QtWidgets/QMainWindow>
#include  <QtCharts/QChartView>
#include  <QtCharts/QBarSeries>
#include  <QtCharts/QBarSet>
#include  <QtCharts/QLegend>
#include  <QtCharts/QBarCategoryAxis>
#include <ctime>  using namespace std::literals;
// using namespace fmt;
using namespace std;
namespace spd = spdlog;
auto console_mainWindow = spd::stdout_color_mt("主界面控制台");
auto rotating_logger_mainWindow = spdlog::rotating_logger_mt("baori_CAO8_Winmain_rotating", "logs/baori_CAO8_rotating.logger", 1048576 * 5, 12);MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);OpenDatabase();//Matlab_mcl_Init();setWindowTitle(QString::fromLocal8Bit("主系统")); // 此处写应用程序在标题栏上显示的名称setStyleSheet("background - color:pink; ");reshow();data_log_tblview();connect(this, &MainWindow::send_cmBox_ToWFC, m_Zanj_WFC_ctrl, &Zanj_WFC_ctrl::cmBox_switch);connect(this, &MainWindow::send_cmBox_ToWFC, m_Zanj_WFC_ctrl, &Zanj_WFC_ctrl::model_switch);connect(this, &MainWindow::send_modelcmBox_ToWFC, m_Zanj_WFC_ctrl, &Zanj_WFC_ctrl::model_switch_0);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::deploy_cmBox_switch()
{if (ui->deploy_cmBox->currentText() == QString::fromLocal8Bit("自动模式")){ui->Iplate4j_IP_QLE->setText("127.0.0.1");ui->model_PC_IP_QLE->setText("127.0.0.1");emit send_cmBox_ToWFC();}else if (ui->deploy_cmBox->currentText() == QString::fromLocal8Bit("手动模式")){emit send_modelcmBox_ToWFC();}
}

02-cmBox_switch()函数实现  

        这里接受信号的计算线程的函数分为两个,第一个cmBox_switch()函数是实现打开配置文件和定时访问数据,定时访问数据这里加入死循环,设置30s的时间间隔。

        startSystem()函数的这段代码是一个无限循环,在每次循环中执行以下操作:

         调用 OnGETSlot() 函数:这个函数用于执行数据读取和预测的操作。具体实现可能涉及从网络或文件系统中读取数据,并对数据进行处理和预测。

         调用 this_thread::sleep_for(chrono::seconds(30)):这行代码会使当前线程暂停执行,模拟定时器或轮询间隔。在这个例子中,线程会休眠30秒钟,然后再次执行循环中的操作。        

        整体来说,这段代码实现了一个简单的定时器功能,每隔30秒钟执行一次数据读取和预测的操作,然后再次休眠30秒钟,循环执行这个过程        


计算线程.cpp文件void Zanj_WFC_ctrl::cmBox_switch()
{configuration_read();startSystem();	
}bool Zanj_WFC_ctrl::configuration_read()
{string err;QFile config_ini("config.ini");//QFile config_ini("config_baori.ini");  打开baori配置文件,如果需要访问宝日大数据平台,就需要打开baori配置文件if (!config_ini.open(QIODevice::ReadOnly | QIODevice::Text)){console_WFC_thread->critical("配置文件config.ini不能打开!");rlogger_WFC_thread->critical("配置文件config.ini不能打开!");//		std::cout << "configuration.ini Open failed." << endl;return false;}console_WFC_thread->info("配置文件config.ini已打开! ");rlogger_WFC_thread->info("配置文件config.ini已打开! ");QTextStream config_txtInput(&config_ini);QString config_lineStr;config_lineStr = config_txtInput.readLine();config_lineStr = config_txtInput.readLine();clientID = config_lineStr.mid(9);config_lineStr = config_txtInput.readLine();clientSecret = config_lineStr.mid(13);config_lineStr = config_txtInput.readLine();serverIP = config_lineStr.mid(9);config_lineStr = config_txtInput.readLine();serviceID_get = config_lineStr.mid(14);config_lineStr = config_txtInput.readLine();serviceID_post = config_lineStr.mid(15);config_lineStr = config_txtInput.readLine();name = config_lineStr.mid(5);config_lineStr = config_txtInput.readLine();unit = config_lineStr.mid(5);config_lineStr = config_txtInput.readLine();user_ID = config_lineStr.mid(8);config_lineStr = config_txtInput.readLine();companyCode = config_lineStr.mid(12);config_lineStr = config_txtInput.readLine();mssql_serverName = config_lineStr.mid(17);config_lineStr = config_txtInput.readLine();mssql_dbName = config_lineStr.mid(13);config_lineStr = config_txtInput.readLine();mssql_username = config_lineStr.mid(15);config_lineStr = config_txtInput.readLine();mssql_pwd = config_lineStr.mid(10);config_lineStr = config_txtInput.readLine();mssql_datasource = config_lineStr.mid(17);return true;
}void Zanj_WFC_ctrl::startSystem() {while (true) {// 每隔一定时间执行一次数据读取和预测OnGETSlot();//Temp_KNNval_Auto_Cal();// 休眠一段时间,模拟定时器或轮询间隔this_thread::sleep_for(chrono::seconds(30)); // 30秒钟间隔}
}

03-model_switch()函数实现  

       实现另一个函数之前,先定义了一个全局变量,用于设置工作模式,这里设置的是,当变量为0,为手动模式,变量为1,为自动模式,在读取数据函数那里,加入if判断语句,如果变量为1,则直接进行计算,否则,需要手动计算

        如果变量为1,直接调用该函数Temp_KNNval_Auto_Cal()进行计算,如果为0,则手动操作进行计算。

计算线程.cpp文件void Zanj_WFC_ctrl::json_doc_get_parse()
{//总的思路是:对象.value(),如果取到string、int、double类型 就直接.toString()等输出;//如果取到object或array类型 ,就通过toObject()或toArray() 转到对象或数组类型,接着取值。。循环if (json_doc_get.isNull()){console_WFC_thread->critical("unable to parse! ");rlogger_WFC_thread->critical("unable to parse! ");}else{console_WFC_thread->info("parse start! ");rlogger_WFC_thread->info("parse start! ");}QJsonObject::Iterator it;for (it = doc_get_Obj.begin(); it != doc_get_Obj.end(); ++it) {HdglPredict tempData;QString aentid, atentid, atime, acode, agrade, asource;float ahthick, athick, awidth, CT_TMP, FT_TMP, DSH, SPEED, TPM;float C, Si, Mn, P, S, Cu, Ni, Cr, Mo, Nb, Ti, B, N, Al;int st_product_no;QString zoneKey = it.key();QJsonObject zoneObj = it.value().toObject();// 检查钢卷是否已经读取过,如果已经读取过,则跳过if (readCoils.contains(zoneKey)){console_WFC_thread->warn("文件里没有其他钢卷! ");continue;}// 将已读取的钢卷添加到集合中readCoils.insert(zoneKey);aentid = zoneObj["aentid"].toString();atentid = zoneObj["atentid"].toString();atime = zoneObj["atime"].toString();acode = zoneObj["acode"].toString();agrade = zoneObj["agrade"].toString();asource = zoneObj["asource"].toString();tempData.ZoneKey = zoneKey;tempData.ENTID = aentid;tempData.AENTID = atentid;tempData.ATIME = atime;tempData.ST_code = acode;tempData.ST_grade = agrade;tempData.ST_source = asource;tempData.CGL_SPEED_INPUT = SPEED;tempData.SPM_ELONG_INPUT = TPM;tempData.st_product_no = st_product_no_determin();// 将结构体对象添加到容器中hdglPredictList.append(tempData);strt_hdgl_predict.ENTID = aentid;strt_hdgl_predict.AENTID = atentid;strt_hdgl_predict.ATIME = atime;strt_hdgl_predict.ST_code = acode;strt_hdgl_predict.ST_grade = agrade;strt_hdgl_predict.ST_source = asource;strt_hdgl_predict.CGL_SPEED_INPUT = SPEED;strt_hdgl_predict.SPM_ELONG_INPUT = TPM;if (model_switch_num == 1){Temp_KNNval_Auto_Cal();} else{continue;}}}void Zanj_WFC_ctrl::model_switch() {model_switch_num = 1;}
void Zanj_WFC_ctrl::model_switch_0() {model_switch_num = 0;}

04-数据存在判断操作实现  

       最后实现系统对平台是否存在新的数据的判断,定义了一个字符串变量readCoils,用于存储已经读取的钢卷,对于已经读取过的钢卷,直接跳过,不进行计算,若是没有钢卷存在,系统也会发出警告。通过下面这部分代码判断即可

        if (readCoils.contains(zoneKey))
        {
            
            console_WFC_thread->warn("文件里没有其他钢卷! ");
            continue;
        }

        // 将已读取的钢卷添加到集合中
        readCoils.insert(zoneKey);

void Zanj_WFC_ctrl::json_doc_get_parse()
{//总的思路是:对象.value(),如果取到string、int、double类型 就直接.toString()等输出;//如果取到object或array类型 ,就通过toObject()或toArray() 转到对象或数组类型,接着取值。。循环if (json_doc_get.isNull()){console_WFC_thread->critical("unable to parse! ");rlogger_WFC_thread->critical("unable to parse! ");}else{console_WFC_thread->info("parse start! ");rlogger_WFC_thread->info("parse start! ");}QJsonObject::Iterator it;for (it = doc_get_Obj.begin(); it != doc_get_Obj.end(); ++it) {HdglPredict tempData;QString aentid, atentid, atime, acode, agrade, asource;float ahthick, athick, awidth, CT_TMP, FT_TMP, DSH, SPEED, TPM;float C, Si, Mn, P, S, Cu, Ni, Cr, Mo, Nb, Ti, B, N, Al;int st_product_no;QString zoneKey = it.key();QJsonObject zoneObj = it.value().toObject();// 检查钢卷是否已经读取过,如果已经读取过,则跳过if (readCoils.contains(zoneKey)){console_WFC_thread->warn("文件里没有其他钢卷! ");continue;}// 将已读取的钢卷添加到集合中readCoils.insert(zoneKey);aentid = zoneObj["aentid"].toString();atentid = zoneObj["atentid"].toString();atime = zoneObj["atime"].toString();acode = zoneObj["acode"].toString();agrade = zoneObj["agrade"].toString();asource = zoneObj["asource"].toString();tempData.ZoneKey = zoneKey;tempData.ENTID = aentid;tempData.AENTID = atentid;tempData.ATIME = atime;tempData.ST_code = acode;tempData.ST_grade = agrade;tempData.ST_source = asource;tempData.CGL_SPEED_INPUT = SPEED;tempData.SPM_ELONG_INPUT = TPM;tempData.st_product_no = st_product_no_determin();// 将结构体对象添加到容器中hdglPredictList.append(tempData);strt_hdgl_predict.ENTID = aentid;strt_hdgl_predict.AENTID = atentid;strt_hdgl_predict.ATIME = atime;strt_hdgl_predict.ST_code = acode;strt_hdgl_predict.ST_grade = agrade;strt_hdgl_predict.ST_source = asource;strt_hdgl_predict.CGL_SPEED_INPUT = SPEED;strt_hdgl_predict.SPM_ELONG_INPUT = TPM;if (model_switch_num == 1){Temp_KNNval_Auto_Cal();} else{continue;}}}

  05-功能演示  

      下面对上述介绍的功能进行演示:

   如下图所示,为系统登录界面,登录之后,才可以对各种功能进行操作。 

         主界面如下图所示:仅展示部分主界面,分为自动模式和手动模式

        选择自动模式之后,就可以持续进行计算,不断进行访问数据文件 

         当再次访问,发现数据文件中没有数据之后,便会发出警告,如下图所示。

 总结      

       在C++ QT系统中实现自动化读取JSON数据文件的过程有几个好处:

        提高效率:自动化读取JSON数据文件可以省去手动操作的时间和精力,提高系统运行效率。特别是在需要定期更新或获取数据时,自动化读取可以保证数据及时可用,减少了人为干预的需要。

        减少错误:手动处理JSON数据文件容易出现错误,例如文件路径错误、解析错误等。自动化读取通过编程实现,可以减少人为错误的发生,提高系统的稳定性和可靠性。

        增强灵活性:自动化读取JSON数据文件的实现可以根据需求进行定制化,例如可以设置读取频率、读取条件等,从而增强了系统的灵活性和可配置性。

        方便维护:通过自动化读取,可以将数据获取的逻辑封装在函数或模块中,便于维护和修改。当需求变化时,只需要修改相应的代码逻辑,而不必修改大量的手动操作步骤。

        综上所述,自动化读取JSON数据文件可以提高系统效率、减少错误、增强灵活性,并方便系统的维护和升级。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/15625.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flink 窗口

窗口&#xff08;Window&#xff09; 窗口是处理无限流的核心。 窗口将流分割成有限大小的“桶”&#xff0c;我们可以计算窗口中的数据。 窗口程序一般有键控流&#xff08;keyed streams&#xff09;的窗口程序 和 非键控流&#xff08;non-keyed streams&#xff09;的窗口…

Rabbitmq 搭建使用案例 [附源码]

Rabbitmq 搭建使用案例 文章目录 RabbitMQ搭建docker 代码golang生产者消费者 可视化消费进度 RabbitMQ搭建 docker docker run -d --hostname rabbitmq --name rabbitmq -e RABBITMQ_DEFAULT_USERadmin -e RABBITMQ_DEFAULT_PASSadmin -e RABBITMQ_DEFAULT_VHOSTmy_vhost -e…

LeetCode/NowCoder-复杂度OJ练习

无论你觉得自己多么的不幸&#xff0c;永远有人比你更加不幸。&#x1f493;&#x1f493;&#x1f493; 目录 说在前面 题目一&#xff1a;消失的数字 题目二&#xff1a;轮转数组 SUMUP结尾 说在前面 dear朋友们大家好&#xff01;&#x1f496;&#x1f496;&#x1f496…

线性表(从数据结构的三要素出发)

文章目录 逻辑结构存储结构顺序存储链式存储单链表双链表循环单链表循环双链表静态链表 数据的操作顺序结构链式结构单链表双链表 逻辑结构 线性表是具有相同数据类型的 n ( n ≥ 0 ) n(n≥0) n(n≥0)个数据元素的有限序列&#xff0c;其中 n n n为表长&#xff0c;当 n 0 n0…

IT行业已经饱和?2024年报考计算机类专业还有出路吗?

&#x1f446;点击关注 获取更多编程干货&#x1f446; “高薪”光环加持&#xff0c;IT行业一直是不少人心仪的职业选择&#xff0c;计算机专业一度成为最热门的本科专业。 然而&#xff0c;正因报考计算机专业、想要入行IT行业的人越来越多&#xff0c;“行业饱和”、“人才…

MySQL(一) 库和表的基础操作

1. 数据库基础 1.1 什么是数据库 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库? 文件保存数据有以下几个缺点&#xff1a; 文件的安全性问题文件不利于数据查询和管理文件不利于存储海量数据文件在程序中控制不方便 数据库存储介质&#xff1a;磁盘内存 为了解…

增强ev代码签名证书2300

代码签名证书是软件开发者们确保软件完整性和安全性的重要工具之一。在各种类型的代码签名证书中&#xff0c;增强EV代码签名证书拥有许多独特的功能而受到企业开发者的欢迎&#xff0c;今天就随SSL盾小编了解增强EV代码签名证书的申请条件以及申请流程。 1.增强型EV代码签名证…

【小程序 按钮 表单 】

按钮 代码演示 xxx.wxml <view class"boss" hover-class"box"hover-start-time"2000"hover-stay-time"5000">测试文本<view hover-stop-propagation"true">子集</view><view>子集2</view>…

相关服务器介绍

服务器是一种高性能的计算机&#xff0c;它被设计用来为其他计算机或终端设备提供服务&#xff0c;如数据处理、文件存储、网络通信等。服务器通常具有强大的计算能力、大容量的存储空间和高效的网络连接能力。 常见的服务器种类及其特点 文件服务器 文件服务器主要负责中央存储…

Echarts图表使用

ECharts是一个用JS实现开源可视化库&#xff0c;它提供了丰富的图表类型和交互能力。使用户可以通过简单的配置生成各种各样的图表。 先安装ECharts图表直接下载echarts.min.js并用<script>标签引入也可以使用源代码版本echarts.js并用<script>标签引入&#xff0…

华为机考入门python3--(29)牛客29-字符串加解密

分类&#xff1a;字符变换 知识点&#xff1a; 字符是字母 char.isalpha() 字符是小写字母 char.islower() 字符是数字 char.isdigit() b变C chr((ord(b) - ord(a) 1) % 26 ord(A)) 题目来自【牛客】 # 加密 def encrypt_string(s):result ""for ch…

【算法】决策单调性优化DP

文章目录 决策单调性四边形不等式决策单调性 形式1法1 分治法2 二分队列例题 P3515Solution 形式2例题 P3195Solution 形式3例题 CF833BSolution 形式4例题Solution 后话 决策单调性 四边形不等式 定义: 对于二元函数 w ( x , y ) w(x,y) w(x,y)&#xff0c;若 ∀ a , b , …

强烈推荐 20.7k Star!企业级商城开源项目强烈推荐!基于DDD领域驱动设计模型,助您快速掌握技术奥秘,实现业务快速增长

更多资源请关注纽扣编程微信公众号 1 项目简介 商城是个从零到一的C端商城项目&#xff0c;包含商城核心业务和基础架构两大模块,推出用户、消息、商品、订单、优惠券、支付、网关、购物车等业务模块&#xff0c;通过商城系统中复杂场景&#xff0c;给出对应解决方案。使用 …

Linux网络编程:HTTP协议

前言&#xff1a; 我们知道OSI模型上层分为应用层、会话层和表示层&#xff0c;我们接下来要讲的是主流的应用层协议HTTP&#xff0c;为什么需要这个协议呢&#xff0c;因为在应用层由于操作系统的不同、开发人员使用的语言类型不同&#xff0c;当我们在传输结构化数据时&…

webpack编译过程

webpack编译过程 初始化 此阶段&#xff0c;webpack会将**CLI参数**、**配置文件**、**默认配置**进行融合&#xff0c;形成一个最终的配置对象。​ 对配置的处理过程是依托一个第三方库yargs完成的 ​ 此阶段相对比较简单&#xff0c;主要是为接下来的编译阶段做必要的准备 ​…

Docker学习(3):镜像使用

当运行容器时&#xff0c;使用的镜像如果在本地中不存在&#xff0c;docker 就会自动从 docker 镜像仓库中下载&#xff0c;默认是从 Docker Hub 公共镜像源下载。 一、列出镜像列表 可以使用 docker images 来列出本地主机上的镜像。 各个选项说明&#xff1a; REPOSITORY&am…

【Linux学习】进程

下面是有关进程的相关介绍&#xff0c;希望对你有所帮助&#xff01; 小海编程心语录-CSDN博客 目录 1. 进程的概念 1.1 进程与程序 1.2 进程号 2. 进程的状态 2.1 fork创建子进程 2.2 父子进程间的文件共享 3. 进程的诞生与终止 3.1 进程的诞生 3.2 进程的终止 1. 进…

使用docker commit创建新镜像

前言 我们知道&#xff0c;从docker-hub上拉取的镜像所创建的容器是最小版本的&#xff0c;比如ubuntu内部是没有vim编辑器的&#xff0c;我们需要自己手动安装&#xff0c;但是当我们安装后假如有人把我们的容器误删了&#xff0c;那么我们再次根据原始镜像创建的容器就没有了…

CCF20230501——重复局面

CCF20230501——重复局面 代码如下&#xff1a; #include<bits/stdc.h> using namespace std; int main() {int n;cin>>n;char a[101][64];int i,j;for(i0;i<n;i){for(j0;j<64;j){cin>>a[i][j];}}int temp0,flag1;for(i0;i<n;i){flag1;for(j0;j<…