在早期开发的软件中,尤其是初学者入门者写的软件,软件运行久了,难免遇到意外崩溃的时候,可是大部分的运行设备可能在现场客户那,需要记住每一次从软件启动后到软件意外关闭前的运行时间,需要记录的信息包括:编号+开始时间+结束时间+已运行时间,每次完整的运行过程只产生一条记录,每次运行时间改变以后更新当前这条记录即可。这样就可以确切的了解到软件在现场的真实运行情况是否糟糕,如果没有这个记录(当然可以选择记录存储到数据库),程序又重启恢复了,也不知道到底每次运行了多久,从几点到几点。
为了写的简单点,不干扰原有的数据库文件,我一般选择输出到文本文件。
完整代码下载: https://download.csdn.net/download/feiyangqingyun/11010447
完整代码:

#ifndef SAVERUNTIME_H
#define SAVERUNTIME_H #include <QObject>
#include <QDateTime>
class QTimer; #ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif class QDESIGNER_WIDGET_EXPORT SaveRunTime : public QObject
#else
class SaveRunTime : public QObject
#endif {
Q_OBJECT
public:
static SaveRunTime *Instance();
explicit SaveRunTime(QObject *parent = ); private:
static QScopedPointer<SaveRunTime> self;
QString path; //日志文件路径
QString name; //日志文件名称 int lastID;
int saveInterval;
QDateTime startTime;
QString logFile;
QTimer *timerSave; private:
void getDiffValue(const QDateTime &startTime, const QDateTime &endTime, int &day, int &hour, int &minute); signals: public slots:
void start(); //启动服务
void stop(); //停止服务
void initLog(); //初始化日志文件
void appendLog(); //追加一条记录到日志文件
void saveLog(); //保存运行时间到日志文件 void setPath(const QString &path);
void setName(const QString &name);
void setSaveInterval(int saveInterval);
}; #endif // SAVERUNTIME_H
#include "saveruntime.h"
#include "qmutex.h"
#include "qapplication.h"
#include "qtimer.h"
#include "qfile.h"
#include "qtextstream.h"
#include "qstringlist.h"
#include "qdebug.h" #ifdef Q_OS_WIN
#define NEWLINE "\r\n"
#else
#define NEWLINE "\n"
#endif QScopedPointer<SaveRunTime> SaveRunTime::self;
SaveRunTime *SaveRunTime::Instance()
{
if (self.isNull()) {
QMutex mutex;
QMutexLocker locker(&mutex);
if (self.isNull()) {
self.reset(new SaveRunTime);
}
} return self.data();
} SaveRunTime::SaveRunTime(QObject *parent) : QObject(parent)
{
path = qApp->applicationDirPath();
QString str = qApp->applicationFilePath();
QStringList list = str.split("/");
name = list.at(list.count() - ).split(".").at(); saveInterval = * * ;
startTime = QDateTime::currentDateTime(); timerSave = new QTimer(this);
timerSave->setInterval(saveInterval);
connect(timerSave, SIGNAL(timeout()), this, SLOT(saveLog()));
} void SaveRunTime::start()
{
timerSave->start(); initLog();
appendLog();
saveLog();
} void SaveRunTime::stop()
{
timerSave->stop();
} void SaveRunTime::getDiffValue(const QDateTime &startTime, const QDateTime &endTime, int &day, int &hour, int &minute)
{
qint64 sec = startTime.secsTo(endTime);
day = hour = minute = ;
int seconds = ; while (sec > ) {
seconds++;
if (seconds == ) {
minute++;
seconds = ;
} if (minute == ) {
hour++;
minute = ;
} if (hour == ) {
day++;
hour = ;
} sec--;
}
} void SaveRunTime::initLog()
{
//判断当前年份的记事本文件是否存在,不存在则新建并且写入标题
//存在则自动读取最后一行的id号 记事本文件格式内容
//编号 开始时间 结束时间 已运行时间
//1 2016-01-01 12:33:33 2016-02-05 12:12:12 day: 0 hour: 0 minute: 0 logFile = QString("%1/%2_runtime_%3.txt").arg(path).arg(name).arg(QDate::currentDate().year());
QFile file(logFile); if (file.size() == ) {
if (file.open(QFile::WriteOnly | QFile::Text)) {
QString strID = QString("%1\t").arg("编号");
QString strStartTime = QString("%1\t\t").arg("开始时间");
QString strEndTime = QString("%1\t\t").arg("结束时间");
QString strRunTime = QString("%1").arg("已运行时间");
QString line = strID + strStartTime + strEndTime + strRunTime; QTextStream stream(&file);
stream << line << NEWLINE;
file.close(); lastID = ;
}
} else {
if (file.open(QFile::ReadOnly)) {
QString lastLine; while (!file.atEnd()) {
lastLine = file.readLine();
} file.close(); QStringList list = lastLine.split("\t");
lastID = list.at().toInt();
}
} lastID++;
} void SaveRunTime::appendLog()
{
logFile = QString("%1/%2_runtime_%3.txt").arg(path).arg(name).arg(QDate::currentDate().year());
QFile file(logFile); //写入当前首次运行时间
if (file.open(QFile::WriteOnly | QFile::Append | QFile::Text)) {
QString strID = QString("%1\t").arg(lastID);
QString strStartTime = QString("%1\t").arg(startTime.toString("yyyy-MM-dd HH:mm:ss"));
QString strEndTime = QString("%1\t").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); int day, hour, minute;
getDiffValue(startTime, QDateTime::currentDateTime(), day, hour, minute);
QString strRunTime = QString("%1 天 %2 时 %3 分").arg(day).arg(hour).arg(minute);
QString line = strID + strStartTime + strEndTime + strRunTime; QTextStream stream(&file);
stream << line << NEWLINE;
file.close();
}
} void SaveRunTime::saveLog()
{
//每次保存都是将之前的所有文本读取出来,然后替换最后一行即可
logFile = QString("%1/%2_runtime_%3.txt").arg(path).arg(name).arg(QDate::currentDate().year());
QFile file(logFile); //如果日志文件不存在,则初始化一个日志文件
if (file.size() == ) {
initLog();
appendLog();
return;
} if (file.open(QFile::ReadWrite)) {
//一行行读取到链表
QStringList content;
while (!file.atEnd()) {
content.append(file.readLine());
} //重新清空文件
file.resize(); //如果行数小于2则返回
if (content.count() < ) {
file.close();
return;
} QString lastLine = content.last();
QStringList list = lastLine.split("\t"); //计算已运行时间
int day, hour, minute;
getDiffValue(startTime, QDateTime::currentDateTime(), day, hour, minute);
QString strRunTime = QString("%1 天 %2 时 %3 分").arg(day).arg(hour).arg(minute); //重新拼接最后一行
list[] = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss");
list[] = strRunTime;
lastLine = list.join("\t"); //重新替换最后一行并写入新的数据
content[content.count() - ] = lastLine; QTextStream stream(&file);
stream << content.join("") << NEWLINE;
file.close();
}
} void SaveRunTime::setPath(const QString &path)
{
if (this->path != path) {
this->path = path;
}
} void SaveRunTime::setName(const QString &name)
{
if (this->name != name) {
this->name = name;
}
} void SaveRunTime::setSaveInterval(int saveInterval)
{
if (this->saveInterval != saveInterval) {
this->saveInterval = saveInterval;
timerSave->setInterval(saveInterval);
}
}

Qt编写软件运行时间记录(开源)的更多相关文章

  1. Qt编写的开源帖子集合(懒人专用)

    回顾自己学习Qt以来九年了,在这九年多时间里面,从本论坛学习不到不少的东西,今天特意整了一下自己开源过的资源的帖子,整理一起方便大家直接跳转下载,不统计不知道,一统计吓一跳,不知不觉开源了这么多代码, ...

  2. Qt编写自定义控件二动画按钮

    现在的web发展越来越快,很多流行的布局样式,都是从web开始的,写惯了Qt widgets 项目,很多时候想改进一下现有的人机交互,尤其是在现有的按钮上加一些动画的效果,例如鼠标移上去变大,移开还原 ...

  3. Qt编写项目作品大全(自定义控件+输入法+大屏电子看板+视频监控+楼宇对讲+气体安全等)

    一.自定义控件大全 (一).控件介绍 超过160个精美控件,涵盖了各种仪表盘.进度条.进度球.指南针.曲线图.标尺.温度计.导航条.导航栏,flatui.高亮按钮.滑动选择器.农历等.远超qwt集成的 ...

  4. Qt编写气体安全管理系统10-数据导出

    一.前言 数据导出一般指导出到excel表格,可能有部分用户还需要导出到pdf,因为pdf基本上不可编辑,防止用户重新编辑导出的数据,excel可能绝大部分用过电脑的人都知道,广为流行,主要就是微软的 ...

  5. Qt编写安防视频监控系统(界面很漂亮)

    一.前言 视频监控系统在整个安防领域,已经做到了烂大街的程序,全国起码几百家公司做过类似的系统,当然这一方面的需求量也是非常旺盛的,各种定制化的需求越来越多,尤其是这几年借着人脸识别的东风,发展更加迅 ...

  6. Qt编写安防视频监控系统18-云台控制

    一.前言 云台控制是视频监控系统中必备的一个功能,对球机进行上下左右的移动,还有焦距的控制,其实核心就是控制XYZ三个坐标轴,为了开发这个模块,特意研究了各种云台控制的方法和开源库比如soap,有些厂 ...

  7. Qt编写气体安全管理系统8-曲线监控

    一.前言 曲线监控模块用的很少,主要就是用来观察某个设备的实时采集的数据和历史采集的数据,可以回放数据,在右侧可以选择对应的通信端口和控制器,然后选择指定的探测器进行观察,从选择的时候开始计时,每个数 ...

  8. Qt编写数据导出到Excel及Pdf和打印数据

    一.前言 用Qt开发已经九年了,期间用Qt做过不少的项目,在各种项目中有个功能很常用,尤其是涉及到数据记录存储的项目,那就是需要对查询的数据进行导出到Excel,或者导出到Pdf文件,或者直接打印查询 ...

  9. Qt编写控件属性设计器7-串口采集

    一.前言 数据源是组态软件的核心灵魂,少了数据源,组态就是个花架子没卵用,一般数据源有三种方式获取,串口.网络.数据库,至于数据规则是什么,这个用户自己指定,本设计器全部采用第一个字节作为数据来演示. ...

随机推荐

  1. 手把手教你 Mockito 的使用

    什么是 Mockito Mockito 是一个强大的用于 Java 开发的模拟测试框架, 通过 Mockito 我们可以创建和配置 Mock 对象, 进而简化有外部依赖的类的测试.使用 Mockito ...

  2. 如何使用Cassandra来存储time-series类型的数据

       Cassandra非常适合存储时序类型的数据,本文我们将使用一个气象站的例子,该气象站每分钟需要存储一条温度数据. 一.方案1,每个设备占用一行      这个方案的思路就是给每个数据源创建一行 ...

  3. Array and Linkedlist区别与操作的时间复杂度(转载)

    转载自:http://blog.csdn.net/tm_wb/article/details/6319146 数组链表堆栈和队列 数组链表堆栈和队列是最基本的数据结构,任何程序都会涉及到其中的一种或多 ...

  4. python3 requests获取某网站折线图上数据

    比如要抓取某网站折线图上数据,如下截图: 借助Chrome开发者工具Network.经过分析发现获取上面的热度数据,找到对应的事件url:https://pcw-api.iqiyi.com/video ...

  5. Visio画流程图风格设置

    第一步:选取设计下选用“简单” 第二步:设置颜色为“铅笔” 第三步:设置效果为“辐射” 第四步:效果

  6. AllJoyn+Android开发案例-android跨设备调用方法

    AllJoyn+Android开发案例-android跨设备调用方法 项目须要涉及AllJoyn开源物联网框架.前面主要了解了一些AllJoyn主要的概念.像总线,总线附件,总线对象,总线接口这种概念 ...

  7. Spring AOP项目应用——方法入参校验 & 日志横切

    转载:https://blog.csdn.net/Daybreak1209/article/details/80591566 应用一:方法入参校验 由于系统多个方法入参均对外封装了统一的Dto,其中D ...

  8. 最新版本Zabbix3.4+Grafana5 整合部署

    一.Grafana简介 Grafana是一个可视化面板(Dashboard),有着非常漂亮的图表和布局展示,功能齐全的度量仪表盘和图形编辑器,支持Graphite.elasticsearch.zabb ...

  9. 【ShoppingPeeker】-基于Webkit内核的爬虫蜘蛛引擎 ShoppingWebCrawler的姊妹篇-可视化任务Web管理

    ShoppingPeeker 这个项目是蜘蛛项目的可视化任务站点. 项目github地址:ShoppingPeeker 开发语言:C# 开发工具:Visual Studio 2017 +.Net Co ...

  10. 修改PHP上传文件大小设置

    问题: 上传MV到服务器发现有最大文件限制: 50M 怎么修改呢? 度娘了一把, 修改php.ini文件的upload_max_filesize = 100M 及 post_max_size = 10 ...