🎩 欢迎来到技术探索的奇幻世界👨💻
📜 个人主页:@一伦明悦-CSDN博客
✍🏻 作者简介: C++软件开发、Python机器学习爱好者
🗣️ 互动与支持:💬评论 👍🏻点赞 📂收藏 👀关注+
如果文章有所帮助,欢迎留下您宝贵的评论,点赞加收藏支持我,点击关注,一起进步!
机缘
不知不觉已经到了第一个创作纪念日,从2021年7月加入CSDN直到2023年9月1日开始书写第一篇博客,中间经历了研究生两年的生活,在研究生学习过程中,需要学习的内容越来越多,有时候很让人力不从心,并且做的很多项目也积累了不少经验,想要将这些分享给大家,希望能带来一些帮助,这就是写博客的初心,初心源于对技术和知识的热爱,也可能源于对实践经验的渴望。
在实战项目中的经验分享中,我在解决问题、应对挑战的过程中开始思考、总结并记录下来,逐渐形成了写作的动力。日常学习过程中的记录则是将学到的知识整理输出,不仅可以加深对知识的理解,也能够与他人分享交流,从中获得更多的反馈和启发。通过文章进行技术交流则是作者展示自己对特定技术领域的理解和见解,与其他技术人员交流讨论,共同探讨问题并找到解决方案。
下面是一些进行写作的主要原因:
(1)来自于实战项目中的经验分享:
在实战项目中积累的很多经验包括在实际项目中遇到的问题、解决方案以及经验教训,可以帮助他人更好地理解和应对类似的挑战。这种分享不仅可以加深自身对问题的理解,还可以为其他人提供宝贵的参考和指导。
在分享实战项目中的经验时,我会详细描述项目的背景和目标,介绍遇到的具体问题或挑战,并说明解决问题的思路和方法。分享自己在解决问题过程中的思考过程、遇到的困难以及如何克服困难的实际操作步骤。同时,还会分享在解决问题中学到的经验教训,以及后续改进的方向和建议。
通过详细地分享实战项目中的经验,读者可以从中汲取宝贵的经验和教训,避免踩坑,提高解决问题的效率和质量。这种分享可以促进技术交流和共同进步。
(2)日常学习过程中的记录:
写博客的另一个原因是日常学习过程中的记录需要是一种非常有益的习惯。通过将自己的学习成果、心得体会以及解决问题的经验记录在博客中,不仅可以加深对知识的理解,还能够帮助自己系统地整理和归纳所学内容。
首先,记录学习过程中的点滴细节和收获可以帮助自己形成学习的闭环。通过不断地总结、整理和输出,可以加深对知识的理解,帮助记忆并巩固所学内容。此外,通过写作的方式,还能够培养自己的思维逻辑能力和表达能力,提高文字表达的水平。
其次,通过在博客中记录学习过程中的内容,还可以与他人分享和交流。其他读者可以从中获得启发、指导或解决问题的思路,形成技术共享和交流的平台。同时,读者的反馈和评论也能够帮助作者不断改进和提升,促进共同进步。
此外,通过博客记录学习过程还可以留下自己的学习足迹和思考轨迹。随着时间的推移,可以回顾自己曾经的学习历程和成长经历,看到自己的进步和成就,激励自己继续前行。
因此,写博客为了日常学习过程中的记录需要不仅有助于个人学习成长,还可以为他人提供有益的信息和启发,促进技术的传播和交流。这种分享精神不仅可以帮助自己成长,也可以造福他人,实现共赢的局面。
(3)通过文章进行技术交流:
还有最重要的一点是通过文章进行技术交流,包括撰写技术性文章,分享自己在特定领域的见解、经验和解决问题的方法,与其他技术人员进行深入的交流和探讨。这种方式不仅可以展示作者的专业知识和技术水平,还能够促进技术领域的交流和共同进步。
首先,通过文章进行技术交流可以展示专业知识和见解。可以通过分享自己在特定技术领域的研究成果、实践经验或者对技术发展的思考,向读者展示自己的专业素养和深度。
其次,通过文章进行技术交流可以促进技术领域的交流和共享。其他技术人员可以通过阅读我的文章,了解到研究成果和经验教训,从中获得启发和指导。同时,读者还可以通过评论和反馈的方式与其进行互动,提出问题、分享见解,共同探讨技术问题并找到解决方案。
此外,通过文章进行技术交流还可以推动技术领域的进步和发展。可以通过分享自己的技术创新和解决方案,为技术领域的发展贡献自己的力量。同时,通过与其他技术人员的交流和合作,可以促进技术的传播和应用,推动技术领域的不断创新和进步。
收获
在创作过程中可能会有很多种收获,这些收获不仅体现在数字指标上,还包括对自身成长和社交网络的积极影响。截至目前为止,共写出48篇原创文章。
粉丝关注:
通过博客的创作,我会吸引到一批粉丝或读者群体。目前为止,粉丝共有642人,铁粉共有25人,这些粉丝可能会定期关注博客更新,或者通过社交媒体分享你的内容,从而扩大影响力和知名度。粉丝的关注不仅可以提升在网络上的影响力,还能够激励持续创作和分享有价值的内容。
正向反馈:
当文章受到读者的欢迎时,会带来各种形式的正向反馈,比如赞、评论、转发和阅读量增加等。共获得点赞815次,收藏652次,积极评论141次,这些反馈不仅是努力的肯定,还能够帮助更好地了解读者的需求和兴趣,指导未来的创作方向。
认识同行:
通过博客的创作,我也结识到许多志同道合的领域同行。这些同行可能是在同一领域从事相关工作或有相似兴趣爱好的人。与他们的交流和互动不仅可以拓展我的人际网络,还能够获得来自不同角度的观点和建议,促进彼此的成长和学习。有时候,这些同行还可能成为未来的合作伙伴或者良师益友,共同探索和解决技术领域的问题。
知识和技能提升:
创作博客需要对所写内容进行深入的思考和研究,这会促使不断地学习和提升自己的知识和技能。在写作的过程中,可能会遇到各种问题和挑战,需要去查阅资料、学习新知识,从而拓展自己的视野和认知。这种持续学习和成长的过程,会使自己不断地进步和提升,成为更优秀的技术人员。
总的来说,博客创作的收获远不止于数字指标,它还包括对自身技术能力和专业素养的提升,对社交网络的扩展和深化,以及对行业内同行的认识和交流。这些收获都是在个人成长和职业发展过程中非常宝贵的。
日常
当前,创作已经成为我的生活中不可或缺的一部分,与我的工作和学习密切相关。
首先,创作已经融入了我的日常工作和学习中。作为一个写作爱好者和技术从业者,我常常利用业余时间来创作博客文章,记录自己的学习心得、技术经验和思考。这些创作不仅是对我个人学习过程的总结和反思,也是对我所从事领域的探索和分享。因此,创作已经成为我学习过程中的一种延伸和补充,有助于我更加深入地理解和应用所学知识。
其次,对于如何平衡创作、工作和学习,我采取了一些策略来保持良好的平衡。首先,我会合理规划时间,将工作、学习和创作合理分配在每天的时间段中,避免出现过度投入其中一项而忽略其他。其次,我注重高效学习和工作,提高任务完成的效率,以腾出更多时间用于创作。此外,我也会不断调整和优化自己的工作和学习计划,根据实际情况调整创作的时间和内容,保持整体的平衡和稳定。
总的来说,创作已经成为我生活的一部分,与工作和学习相互交织、相互促进。通过合理规划和管理时间,我能够保持良好的平衡,充分发挥创作在我的学习和工作中的作用,不断提升自己的能力和影响力。
成就
过去写得最好的一段代码是在一个大型项目中,里面的代码详细内容位于这篇博客中[C++ QT项目实战]----C++ QT系统实现多线程通信-CSDN博客 这里将主要代码块筛选出来如下:
系统多线程实现
这里讲解四个实现函数文件,其实是两个文件:mainwindow.h和mainwindow.cpp文件为主线程文件,Zanj_WFC_ctrl.h和Zanj_WFC_ctrl.cpp文件为子线程文件,下面一一解释。
mainwindow.cpp文件
(1)、该文件用于实现显示主线程中的主界面,也就是运行之后,第一个界面,可以在界面上进行操作,后台信息是由于spdlog日志信息的导入,才会进行信息显示,便于观察,#include "spdlog/spdlog.h",代码中下面这一部分就是建立子线程的核心,QT中可以使用moveToThread()函数建立新线程。具体介绍如下:
a、m_Zanj_WFC_ctrl = new Zanj_WFC_ctrl;// 这个实例要负责预报计算任务
b、m_Zanj_WFC_ctrl_Thread = new QThread; // 子线程,本身不负责预报计算
c、connectZanj_WFC_ctrl(m_Zanj_WFC_ctrl); // 连接信号-槽,复制的开始和取消指令是通过信号发送的
d、m_Zanj_WFC_ctrl->moveToThread(m_Zanj_WFC_ctrl_Thread);// 将实例移动到新的线程,实现多线程运行
e、m_Zanj_WFC_ctrl_Thread->start();
(2)、函数connectZanj_WFC_ctrl()用于连接子线程函数,里面有该函数实现的功能,使用connect()函数编写代码: connect(this, SIGNAL(system_predict_init_link()), m_Zanj_WFC_ctrl, SLOT(HDGL_SYSTEM_Init()));这个函数HDGL_SYSTEM_Init()在子线程中实现,也就是说只要主线程启动,子线程也会跟着启动,可以在该函数中实现子线程的功能。
(3)、上述描述的主线程与子线程通信的案例中的实现过程如下:也是通过信号与槽函数方式,比如打开配置文件函数,首先对该函数进行实现on_Open_config_Btn_clicked(),该函数就是打开配置文件控件对应的函数,该函数实现了点击按钮之后,发送了信号emit send_config();该信号通过connect()函数发送到子线程,代码为connect(this, &MainWindow::send_config, m_Zanj_WFC_ctrl, &Zanj_WFC_ctrl::OnconfigSlot);OnconfigSlot()函数在子线程中实现。
原理就是这样,虽有些繁琐,但是逻辑性强。另一个读取数据按钮原理一样。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "Zanj_WFC_ctrl.h"
#include "qdebug.h"
#include <qstring.h>#include "cglobal.h"
#include <QElapsedTimer>
#include <iostream>
#include "windows.h"
#pragma comment(lib,".\\lib\\fmtd.lib")#include "spdlog/fmt/ostr.h"
#include "spdlog/spdlog.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/rotating_file_sink.h"#include <QTimer>
#include <time.h>
#include <QLabel>
#include <QValueAxis>
#include <QMargins>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>#include <ctime> using namespace std::literals;
using namespace std;
namespace spd = spdlog;
auto console_mainWindow = spd::stdout_color_mt("主界面控制台");
auto rotating_logger_mainWindow = spdlog::rotating_logger_mt("CAO8_Winmain_rotating", "logs/CAO8_rotating.logger", 1048576 * 5, 12);MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);setWindowTitle(QString::fromLocal8Bit("主系统")); // 此处写应用程序在标题栏上显示的名称setStyleSheet("background - color:pink; ");reshow();data_log_tblview();console_mainWindow->info("欢迎进入主系统UI线程[Mainwindow]!");rotating_logger_mainWindow->info("欢迎进入主系统UI线程[Mainwindow]!");m_Zanj_WFC_ctrl = new Zanj_WFC_ctrl;// 这个实例要负责预报计算任务m_Zanj_WFC_ctrl_Thread = new QThread; // 子线程,本身不负责预报计算connectZanj_WFC_ctrl(m_Zanj_WFC_ctrl); // 连接信号-槽,复制的开始和取消指令是通过信号发送的m_Zanj_WFC_ctrl->moveToThread(m_Zanj_WFC_ctrl_Thread);// 将实例移动到新的线程,实现多线程运行m_Zanj_WFC_ctrl_Thread->start();emit system_predict_init_link();// 向子线程发送打开配置文件信息connect(this, &MainWindow::send_config, m_Zanj_WFC_ctrl, &Zanj_WFC_ctrl::OnconfigSlot);// 向子线程发送读取数据信号,子线程接收后,进行数据读取connect(this, &MainWindow::send_rChk_ToWFC, m_Zanj_WFC_ctrl, &Zanj_WFC_ctrl::OnGETSlot);}MainWindow::~MainWindow()
{delete ui;
}// 这里连接子线程,进行子线程的开启,子线程连接数据库,连接大数据平台,打开所需文件的信号传递,以及MainWindow界面槽函数处理信号的实现
void MainWindow::connectZanj_WFC_ctrl(Zanj_WFC_ctrl * m_Zanj_WFC_ctrl)
{connect(this, SIGNAL(system_predict_init_link()), m_Zanj_WFC_ctrl, SLOT(HDGL_SYSTEM_Init()));// 使用信号-槽机制,发出开始指令}// 打开配置文件函数
void MainWindow::on_Open_config_Btn_clicked()
{ui->Iplate4j_IP_QLE->setText("127.0.0.1");ui->model_PC_IP_QLE->setText("127.0.0.1");emit send_config();
}// 由主窗口发送数据读取信号,子线程实现数据读取操作
void MainWindow::on_Restful_data_read_Btn_clicked()
{emit send_rChk_ToWFC();}
mainwindow.h文件
该文件就是.cpp文件中众多函数的声明,以及信号的声明,比如读取数据时发送的信号需要在这里声明一下,便于使用。Zanj_WFC_ctrl * m_Zanj_WFC_ctrl; // 预报计算的类
QThread * m_Zanj_WFC_ctrl_Thread; //将被移动到此线程执行,这里也定义了指针,用于在.cpp文件中使用。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include"ui_mainwindow.h"
#include <QMainWindow>
#include <QLabel>
#include <QtSql/QtSql>#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 <QMouseEvent>
//一定要声明!!!
#include"dialog_data_log.h"
//#include<vector>//#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);private slots :void on_Restful_data_read_Btn_clicked(); //点击平台数据读取按钮,实现读取数据信号发送 void on_Open_config_Btn_clicked();signals:void system_predict_init_link();//定义向子线程发送的信号,用于实现子线程开启void send_config(); // 定义向子线程发送打开配置文件的信号void send_rChk_ToWFC(); // 定义向子线程发送数据读取的信号private:Ui::MainWindow *ui;QLabel * pLabel;};#endif // MAINWINDOW_H
Zanj_WFC_ctrl.cpp文件
(1)、该文件中的众多函数就是对主线程发送的信号的实现过程,当接受到主线程的信号之后,如果需要对其进行处理,便可以在这里定义函数实现过程,该HDGL_SYSTEM_Init()函数就是对主线程中connectZanj_WFC_ctrl()连接函数的实现。
(2)、案例中主线程发送读取数据信号,子线程中函数的实现OnGETSlot()在该文件中,这里适用于读取数据函数的实现,可以根据需要进行修改。打开配置文件的实现原理与之一致。
#include "Zanj_WFC_ctrl.h"
#include "wfc_to_main.h"
#include <Python.h>
#include "qdebug.h"
#include <qstring.h>
#include <Python.h>#pragma comment(lib,"mclmcrrt.lib")
#pragma comment(lib,"libmx.lib")
#pragma comment(lib,"libmat.lib")
#pragma comment(lib,"mclmcr.lib")
#pragma comment(lib,".\\lib\\CGL_Mech_Property_BP_pred.lib")
#pragma comment(lib,".\\lib\\fmtd.lib")#include <QAxObject>
#include <QStandardPaths>
#include <QEventLoop>
#include <QDesktopWidget>#include <algorithm>
#include <numeric>
#include <vector>
#include <QVector>
#include <stdlib.h>#include "spdlog/fmt/ostr.h"
#include "spdlog/spdlog.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/rotating_file_sink.h"using namespace libxl;
using namespace std::literals;
//using namespace fmt;
using namespace std;
namespace spd = spdlog;
auto console_WFC_thread = spd::stdout_color_mt("WFC计算线程 ");
auto rlogger_WFC_thread = spdlog::rotating_logger_mt("CAO8_WFC_thread_rotating", "logs/CAO8_rotating.logger", 1048576 * 5, 12);int Zanj_WFC_ctrl::HDGL_SYSTEM_Init()
{rlogger_WFC_thread->flush_on(spd::level::debug);console_WFC_thread->info("欢迎进入主系统计算线程");str_info = QString::fromLocal8Bit("0 应用程序环境路径 ") + path_deploy;return 1;
}void Zanj_WFC_ctrl::OnGETSlot()
{QString strMessage;QString strResult;QString strUrl;QString strInput;QFile file(QApplication::applicationDirPath() + "/1.json");if (!file.open(QIODevice::WriteOnly)) {console_WFC_thread->error("Json file open failed! ");rlogger_WFC_thread->error("Json file open failed! ");}else {console_WFC_thread->info("Json file open successfully! ");rlogger_WFC_thread->info("Json File open successfully! ");}//QString strInput = ui.textEdit_input->toPlainText();//strUrl += "http://" + ui.lineEdit_Url->text();strUrl = serverIP + serviceID_get;strInput = clientSecret;SendAndGetText(strUrl, get1, strInput, strMessage, strResult);QJsonParseError jsonError;QByteArray byteResult = strResult.toUtf8();//QString转QByteArray//QJsonDocument json = QJsonDocument::fromJson(byteResult, &jsonError);json_doc_get = QJsonDocument::fromJson(byteResult, &jsonError);if (json_doc_get.isNull()){console_WFC_thread->critical("json文件为空文档");//console->critical("jsonError错误类型" + jsonError.errorString().toStdString());//qDebug() << jsonError.errorString();rlogger_WFC_thread->critical("json格式错误[json_doc_get_slot]");//qDebug() << "json格式错误";//注意:如果文档中有中文,就会报格式错误}else if (jsonError.error != QJsonParseError::NoError){console_WFC_thread->critical("json格式错误[json_doc_get_slot]" + jsonError.errorString().toStdString());//qDebug() << jsonError.errorString();rlogger_WFC_thread->critical("json格式错误[json_doc_get_slot]");}else {if (json_doc_get.isObject()) {doc_get_Obj = json_doc_get.object();}}json_doc_get_parse();
// RT_Iplat4j_Communication(); //放在这里可以在主窗口点击数据读取按钮之后,才会提示是否数据平台连接成功file.write(json_doc_get.toJson(QJsonDocument::Indented)); //Indented:表示自动添加/n回车符file.close();}void Zanj_WFC_ctrl::OnconfigSlot()
{configuration_read();
}
Zanj_WFC_ctrl.h文件
该文件也是.cpp文件中众多函数的声明,比如处理读取数据时发送的信号的函数需要在这里声明一下,便于使用。
#pragma once#include <QObject>
#include <QtSql/QtSql>
#include <QVariant>//#include <connection.h>
//#include <QSql>
#include <QSqlError>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QDebug>
#include <QMessageBox>
#include <QEventLoop>
#include <qstring.h>
#include <string>
#include "snap7.h"
#include <QtCore/QJsonObject>
#include <QtCore/QJsonDocument>
#include <Python.h>class Zanj_WFC_ctrl : public QObject
{Q_OBJECTpublic:Zanj_WFC_ctrl(QObject *parent=0);~Zanj_WFC_ctrl();public slots:int HDGL_SYSTEM_Init();void OnGETSlot();void OnconfigSlot();
憧憬
基于以上内容,我的憧憬主要涉及职业规划和创作规划两个方面。
职业规划:
基于我对技术领域的热爱和专业知识的积累,我希望在未来能够在技术领域取得更进一步的发展。我憧憬能够成为该领域的专家或领军人物,为行业发展和创新做出积极贡献。
我希望能够在职业生涯中不断学习和成长,掌握更多先进的技术和方法,拓展自己的技能树,并通过实际项目和研究实践将所学知识转化为实际成果。
我也期待能够在职业发展的过程中,不断挑战自我,突破自己的局限,不断追求卓越,成为行业内的领军人物和创新者。
创作规划:
在创作方面,我希望能够继续坚持不懈地写作,并保持高质量和高频率的创作输出。我憧憬能够建立起自己在技术领域的个人品牌和影响力,成为该领域的权威人士之一。
我计划通过持续不断地创作优质内容,吸引更多的读者和粉丝,建立起自己的读者群体,并与他们建立起良好的互动和交流关系,从而形成一个活跃的社区。
同时,我也希望通过创作来推动技术领域的发展和进步,分享自己的经验和见解,促进技术领域的交流和合作,共同推动行业的发展。
我的憧憬是在未来的职业生涯中不断成长和进步,在技术领域取得更多的成就和影响力,并通过持续不断的创作来实现个人价值和行业贡献。