Qt线程写日志

之前没有考虑写日志时采用单独的线程,而是将写日志的部分放在了主线程中实现,后面发现当程序输出的日志信息过多,程序长时间运行后会造成主线程的运行性能降低。故尝试创建一个单独的线程用来写日志。
此程序有一个弊端,运行时没有错误,但存在文件没有关闭,线程也不清楚结束了没,望大神加以指导修改将其完善。
程序的结构如下:
在这里插入图片描述
运行效果截图:
在这里插入图片描述
上图是第一个界面,密码和用户名为123,点击进入后弹出一个对话框,点击取消后原本填入的信息会被清除,密码验证不通过会弹出提示框。
在这里插入图片描述
此项目是基于应用程序的项目,以QDialog为基类,含有两个ui文件,分别为登录窗口和登录成功后显示的窗口,登录窗口中在两个输入的行编辑器中进行设置属性plcaeholderText,如下图:
在这里插入图片描述
输入的密码显示框还需再设置属性echoMode和placeholderText属性。
在这里插入图片描述
直接上代码:
main.cpp

#include "dialog.h"#include <QApplication>int main(int argc, char *argv[])
{if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QApplication a(argc, argv);Dialog w;w.show();return a.exec();
}

主程序中添加以下代码:

if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

是为了解决在ui界面设计的界面,通过预览查看其效果正常,但是运行程序时部分部件位置显示不正常的问题,在以前的博文中有所记录。
dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include "welcomdlg.h"
#include "writelog.h"QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACEclass Dialog : public QDialog
{Q_OBJECTpublic:Dialog(QWidget *parent = nullptr);~Dialog();void checkedLoginInInfo();void outPutLogMsg(QString strInfo,QString strIndex);protected:
//    void closeEvent(QCloseEvent *event);
signals:void signalSendLogMsg(QString strMsg);private slots:void on_enterButton_clicked();void on_cancelButton_clicked();private:Ui::Dialog *ui;WelcomDlg *m_welcomDlg;WriteLog  *m_writeLog;
};
#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"
#include <QDebug>
#include <QMessageBox>
#include <QDateTime>Dialog::Dialog(QWidget *parent): QDialog(parent), ui(new Ui::Dialog)
{ui->setupUi(this);m_welcomDlg = new WelcomDlg(this);m_writeLog = WriteLog::getInstance();connect(this,&Dialog::signalSendLogMsg,m_writeLog,&WriteLog::slot_receMsg);
}Dialog::~Dialog()
{delete ui;
}void Dialog::checkedLoginInInfo()
{QString str = QString("%1 :%2(%3): ").arg(__FILE__).arg(__FUNCTION__).arg(__LINE__);outPutLogMsg("开始验证登录信息!",str);QString strAccount = ui->lineEditAccount->text().trimmed();QString strPassword = ui->lineEditPassword->text();QString strMsg = "用户名:" + strAccount + "密码:" + strPassword;QString strInfo = QString("%1 :%2(%3): ").arg(__FILE__).arg(__FUNCTION__).arg(__LINE__);outPutLogMsg(strMsg,strInfo);if(strAccount.compare("123") == 0 && strPassword.compare("123") == 0)//大小写敏感的{QString str = QString("%1 :%2(%3): ").arg(__FILE__).arg(__FUNCTION__).arg(__LINE__);outPutLogMsg("登录信息正确!",str);accept();//隐藏模式对话框m_welcomDlg->show();}else{QString str = QString("%1 :%2(%3): ").arg(__FILE__).arg(__FUNCTION__).arg(__LINE__);outPutLogMsg("登录信息输入错误!",str);QMessageBox::warning(this,tr("警告"),tr("用户名或密码错误,请重新输入!"),QMessageBox::Yes);on_cancelButton_clicked();ui->lineEditAccount->setFocus();}
}void Dialog::outPutLogMsg(QString strInfo,QString strIndex)
{QString strTime = QDateTime::currentDateTime().toString("yyyy-MM-dd: hh:mm:ss");strIndex.prepend(strTime);strIndex.append(strInfo);emit signalSendLogMsg(strIndex);
}//void Dialog::closeEvent(QCloseEvent *event)
//{
//    QString str = QString("%1 :%2(%3): ").arg(__FILE__).arg(__FUNCTION__).arg(__LINE__);
//    outPutLogMsg("执行关闭事件",str);
//    Q_UNUSED(event);
//    m_writeLog->closeFileThread();
//}void Dialog::on_enterButton_clicked()
{checkedLoginInInfo();
}void Dialog::on_cancelButton_clicked()
{ui->lineEditAccount->clear();//清空之后,恢复原来的提示文字ui->lineEditPassword->clear();QString strMsg = QString::number(0);strMsg = strMsg.prepend("数据被清空为:");QString str = QString("%1 :%2(%3): ").arg(__FILE__).arg(__FUNCTION__).arg(__LINE__);outPutLogMsg(strMsg,str);
}

welcomdlg.h

#ifndef WELCOMDLG_H
#define WELCOMDLG_H#include <QDialog>
#include "writelog.h"namespace Ui {
class WelcomDlg;
}class WelcomDlg : public QDialog
{Q_OBJECTpublic:explicit WelcomDlg(QWidget *parent = nullptr);~WelcomDlg();void outPutLogMsg(QString strInfo,QString strIndex);signals:void signalSendLogMsg(QString strMsg);
private:Ui::WelcomDlg *ui;WriteLog *m_writeLog;
};#endif // WELCOMDLG_H

welcomdlg.cpp

#include "welcomdlg.h"
#include "ui_welcomdlg.h"
#include <QDateTime>WelcomDlg::WelcomDlg(QWidget *parent) :QDialog(parent),ui(new Ui::WelcomDlg)
{ui->setupUi(this);m_writeLog = WriteLog::getInstance();connect(this,&WelcomDlg::signalSendLogMsg,m_writeLog,&WriteLog::slot_receMsg);QString str = QString("%1 :%2(%3): ").arg(__FILE__).arg(__FUNCTION__).arg(__LINE__);outPutLogMsg("执行欢迎界面的构造函数!",str);
}WelcomDlg::~WelcomDlg()
{QString str = QString("%1 :%2(%3): ").arg(__FILE__).arg(__FUNCTION__).arg(__LINE__);outPutLogMsg("执行欢迎界面的析构函数!",str);delete ui;
}void WelcomDlg::outPutLogMsg(QString strInfo,QString strIndex)
{QString strTime = QDateTime::currentDateTime().toString("yyyy-MM-dd: hh:mm:ss");strIndex.prepend(strTime);strIndex.append(strInfo);emit signalSendLogMsg(strIndex);
}

writedlg.h

#ifndef WRITELOG_H
#define WRITELOG_H#include <QObject>
#include <QMutex>
#include <QThread>
#include <QQueue>
#include <QFile>
#include <QTextStream>#define LOG_NAME "/log.txt"class WriteLog : public QObject
{Q_OBJECT
private:explicit WriteLog(QObject *parent = nullptr);void openLogFile();void writeLogInfo();
public:static WriteLog * getInstance();~WriteLog();//    void closeFileThread();
signals:public slots:void slot_receMsg(QString str);void slot_threadStarted();
//    void slot_threadFinished();
private:static QMutex m_mutex;static WriteLog *m_instance;QThread m_thread;QQueue<QString>  m_queue;QFile *m_file;
//    QTextStream *m_textStream;//似乎不能chuang创建指针
};#endif // WRITELOG_H

writedlg.cpp

#include "writelog.h"
#include <QMutexLocker>
#include <QCoreApplication>
#include <QDateTime>
#include <QDir>QMutex WriteLog::m_mutex;
WriteLog *WriteLog::m_instance = nullptr;
WriteLog::WriteLog(QObject *parent): QObject(parent)
{//创建或打开日志文件openLogFile();this->moveToThread(&m_thread);connect(&m_thread,&QThread::started,this,&WriteLog::slot_threadStarted);connect(&m_thread,&QThread::finished,this,&QObject::deleteLater);m_thread.start();
}void WriteLog::openLogFile()
{QString logDir = QCoreApplication::applicationDirPath() + "/log/" + QDateTime::currentDateTime().toString("yyyy-MM-dd");QDir dir(logDir);if(!dir.exists()){dir.mkpath(logDir);}logDir += LOG_NAME;m_file = new QFile(logDir);if(!m_file->open(QFile::WriteOnly | QFile::Text |QFile::Append));{return ;}
//    m_textStream = new QTextStream(m_file);
}void WriteLog::writeLogInfo()
{if(m_queue.isEmpty()){return ;}QString strMsg = m_queue.front();m_queue.pop_front();QTextStream textStream(m_file);textStream<<strMsg<<"\r\n";m_file->flush();//将缓存区数据刷新到文件中
}WriteLog *WriteLog::getInstance()
{if(m_instance == nullptr){QMutexLocker locker(&m_mutex);m_instance = new WriteLog;}return m_instance;
}WriteLog::~WriteLog()//没有执行析构
{//关闭日志文件,退出线程
//    QString preStr1("====================================End:");
//    QString time = QDateTime::currentDateTime().toString("yyyy-MM-dd");
//    QString preStr2("====================================");
//    if(m_file != nullptr)
//    {
//        m_file->close();
//        delete m_file;
//        m_file = nullptr;
//    }//    m_thread.quit();
//    m_thread.wait();
}//void WriteLog::closeFileThread()
//{
//    QString preStr1("====================================End:");
//    QString time = QDateTime::currentDateTime().toString("yyyy-MM-dd");
//    QString preStr2("====================================");
//    preStr1 += time + preStr2 + "\r\n";
//    m_queue.push_back(preStr1);
//    writeLogInfo();
    if(m_file != nullptr)
    {
        m_file->close();
        delete m_file;
        m_file = nullptr;
    }    m_thread.requestInterruption();
    m_thread.quit();
    m_thread.wait();
//}void WriteLog::slot_receMsg(QString str)
{m_queue.push_back(str);writeLogInfo();
}void WriteLog::slot_threadStarted()
{QString preStr1("====================================Begin:");QString time = QDateTime::currentDateTime().toString("yyyy-MM-dd");QString preStr2("====================================");preStr1 += time + preStr2 + "\r\n";QString str = QString("%1 :%2(%3): ").arg(__FILE__).arg(__FUNCTION__).arg(__LINE__);QString strTime = QDateTime::currentDateTime().toString("yyyy-MM-dd: hh:mm:ss");QString info("写日志线程启动");strTime += str;info.prepend(strTime);info.prepend(preStr1);m_queue.push_back(info);writeLogInfo();
}//void WriteLog::slot_threadFinished()
//{
    qDebug()<<"线程完成!";
//    m_queue.push_back("写日志线程结束");
//    writeLogInfo();
//}

以上程序的编译环境是在qt5.13.2,用的编译器为MinGW32。程序运行正常,但自我感觉日志文件被打开写日志接束后没有关闭,线程没有关闭,自己尝试过关闭线程与文件,但都无法很好的解决,望大神指导。

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

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

相关文章

京解之才——2019年技术盘点微服务篇(三)| 程序员硬核评测

戳蓝字“CSDN云计算”关注我们哦&#xff01;程序员硬核测评&#xff1a;客观、高效、不说软话。无论是技术质量、性能水平&#xff0c;还是工具筛选&#xff0c;一测便知&#xff01;过去几年来&#xff0c;“微服务架构”方兴未艾&#xff0c;尽管这种架构风格没有确切的定义…

Linux环境安装并配置Maven

一、Linux环境安装并配置Maven 1. 进入官网下载Tomat安装包2. 解压安装Tomcat3. 配置可执行权限4. 配置可执行端口&#xff08;避免端口冲突&#xff09;5. 验证Tomcat是否可以正常启动和停止 1. 进入Maven官网复制下载地址下载maven maven官网&#xff1a;http://maven.apach…

OpenGL 色阶

目录 一.OpenGL 色阶 1.Windows OpenGL ES 版本2.Windows OpenGL 版本 二.OpenGL 色阶 GLSL Shader三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 特效 …

Qt中全局变量的使用

一般在项目中想要定义一个变量可以被多个类进行访问&#xff0c;此时就可以定义全局变量。习惯上会将项目中所有类都用到的变量&#xff0c;集中定义在一个头文件中&#xff0c;使用时只需包含此头文件。但是对于我这样基础不牢靠的人&#xff0c;就犯了一个错误&#xff0c;而…

强推!2019年最火的容器、K8S和DevOps入门都在这了

戳蓝字“CSDN云计算”关注我们哦&#xff01;技术头条&#xff1a;干货、简洁、多维全面。更多云计算精华知识尽在眼前&#xff0c;get要点、solve难题&#xff0c;统统不在话下&#xff01;作者&#xff1a; Pasca来源&#xff1a;蛋蛋团&#xff08;ID&#xff1a;dandan_tua…

Tomcat10 下载和配置 Linux 环境

文章目录1. 下载Tomat2. 复制链接地址3. 下载4. 解压Tomcat5. 赋予权限6. 启动tomcat7. 监控日志8. linux防火墙9. 浏览器验证1. 下载Tomat tomcat官网&#xff1a;https://tomcat.apache.org/download-10.cgi 2. 复制链接地址 3. 下载 wget https://downloads.apache.org/t…

qt求一个区间的随机数

举例说明&#xff1a; 求65-90之间的随机数 qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); quint8 ch (quint8)qrand()%25 65;先种随机数种子&#xff0c;然后求随机数。65到90之间相差25&#xff0c;先求0-25的随机数&#xff0c;然后在此基础上加65&#xff0c;其范…

Elastic全球用户大会Elastic{ON}首次落地北京

2019年4月10日&#xff0c;全球领先的大数据搜索软件公司Elastic&#xff08;Elasticsearch和Elastic Stack的开发公司&#xff09;一年一度的全球用户大会Elastic首次来到中国&#xff0c;在北京盛大开幕。来自全国的开发人员、合作伙伴和IT行业人士齐聚一堂&#xff0c;了解和…

Jenikns新建节点、配置节点、新建任务、配置任务、脚本验证

Jenkins节点概念&#xff1a; 1、Jenkins的节点就相当于一个服务器的环境配置容器 2、Jenkins的节点可以是多个的&#xff0c;一个UATEnv节点相当于一个UAT环境配置容器 3、Jenkins的节点就相当于把一个服务器的环境配置信息&#xff0c;都配置到了节点中&#xff0c;运行节点就…

Windows OpenGL ES 图像色阶

目录 一.OpenGL ES 图像色阶 1.原始图片2.效果演示 二.OpenGL ES 图像色阶源码下载三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 特效 零基础 OpenGL E…

qt使用动画提示正在载中

当程序加载较慢的时候&#xff0c;为了告知用户正在加载&#xff0c;需要在界面上显示正在加载中的提示。下面简单说一下自己使用中出现的问题。 一、在主线程中使用动画加载 创建基于qapplication的项目&#xff0c;以qdialog类为基类&#xff0c;有.ui文件。 项目的结构如下…

云存储精华问答 | 云存储的优势在哪?

云存储是一种网上在线存储&#xff08;英语&#xff1a;Cloud storage&#xff09;的模式&#xff0c;即把数据存放在通常由第三方托管的多台虚拟服务器&#xff0c;而非专属的服务器上。今天就让我们来看看关于云陈存储的精华问答吧。1Q&#xff1a;云存储是如何分类的&#x…

Github上Fork部署应用程序

Github上Fork部署应用程序 1. Fork简述及作用2. 登录Github&#xff0c;搜索项目3. Github上打开fork的部署应用4. 点击Fork&#xff0c;并确认邮件5. 登录自己的github&#xff0c;查看fork的项目 1. Fork简述及作用 Fork作用&#xff1a;获得代码修改的权限 简述&#xff1a…

Windows OpenGL 图像色阶

目录 一.OpenGL 图像色阶 1.原始图片2.效果演示 二.OpenGL 图像色阶源码下载三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 特效 零基础 OpenGL ES 学习…

qt解决循环创建的控件,每个都绑定相同的槽函数时出现的一对多响应问题

应用场景 若需要在程序运行期间根据控件数动态创建控件&#xff0c;且创建的每一个控件在某一个信号发生时会触发相同的槽函数。 问题描述 上述所导致的问题是在触发其中一个控件的时候&#xff0c;其它的控件也会响应该槽函数&#xff0c;出现了一对多的绑定。 示例 clas…

用栈和队列分别实现求解迷宫问题(c++,c)

求解迷宫问题&#xff1a;给定一个迷宫要求输出其路径。 给出的迷宫如下&#xff08;可自行更改&#xff09; 可用两种方法实现1.栈2.队列 用栈只能找到路但路不是最简的最简的要用队列实现 用栈实现&#xff08;解析都在代码里了&#xff09; c&#xff08;实现&#xff0…

高达100亿美元!美国国防部将IBM和甲骨文双双踢出了云计算合同;华为任正非说了,华为对向苹果等对手出售5G芯片保持开放的态度...

关注并标星星CSDN云计算极客头条&#xff1a;速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;每周三次&#xff0c;打卡即read更快、更全了解泛云圈精彩newsgo go go 微软全数位版本Xbox One S&a…

OpenGL 灰度图

目录 一.OpenGL 灰度图 1.IOS Object-C 版本1.Windows OpenGL ES 版本2.Windows OpenGL 版本 二.OpenGL 灰度图 GLSL Shader三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 &…

将Github中Fork的代码,克隆到本地

将Github中Fork的代码&#xff0c;克隆到本地 1. 在Github打开Fork的工程2. 单击clone or download按钮&#xff0c;复制Github克隆链接3.进入本地需要存储应用源程序的路径 将源代码clone到本地 1. 在Github打开Fork的工程 登录Github&#xff0c;点击Fork的项目即可&#xf…

Windows OpenGL ES 图像灰度图

目录 一.OpenGL ES 图像灰度图 1.原始图片2.效果演示 二.OpenGL ES 图像灰度图源码下载三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 特效 零基础 Open…