Qt开源作品10-代码统计组件
一、前言
代码行数统计主要用来统计项目中的所有文件的代码行数,其中包括空行、注释行、代码行,可以指定过滤拓展名,比如只想统计.cpp的文件,也可以指定文件或者指定目录进行统计。写完这个工具第一件事情就是统计了一下自己写过的最大的项目大概多少行代码,看下是不是传说中的一行代码一块钱,这个最大的项目从2010年开始的,到现在差不多快10年了,是自己在现在公司写过的最大的项目,一直在升级更新完善,途中重构过两次,大的结构改动,统计了下好像有15W行左右的代码,纯代码大概在10W,其余是空行和注释行,着实把自己吓了一跳,还算是中型项目了,然后又统计了下自定义控件的所有代码,我勒个去,总代码23W行,纯代码17W行呢,哎呀我去!
主要功能:
- 可分别统计代码行/空行/注释行
- 支持指定过滤拓展名
- 支持指定文件或者指定目录进行统计
- 分步显示统计结果,不卡主界面
- 分别展示每个统计过的文件的大小/总行数/代码行数等
二、代码思路
void frmCountCode::countCode(const QString &filePath)
{
QDir dir(filePath);
foreach (QFileInfo fileInfo , dir.entryInfoList()) {
if (fileInfo.isFile()) {
QString strFileName = fileInfo.fileName();
if (checkFile(strFileName)) {
listFile << fileInfo.filePath();
}
} else {
if(fileInfo.fileName() == "." || fileInfo.fileName() == "..") {
continue;
}
//递归找出文件
countCode(fileInfo.absoluteFilePath());
}
}
}
void frmCountCode::countCode(const QStringList &files)
{
int lineCode;
int lineBlank;
int lineNotes;
int count = files.count();
on_btnClear_clicked();
ui->tableWidget->setRowCount(count);
quint32 totalLines = 0;
quint32 totalBytes = 0;
quint32 totalCodes = 0;
quint32 totalNotes = 0;
quint32 totalBlanks = 0;
for (int i = 0; i < count; i++) {
QFileInfo fileInfo(files.at(i));
countCode(fileInfo.filePath(), lineCode, lineBlank, lineNotes);
int lineAll = lineCode + lineBlank + lineNotes;
QTableWidgetItem *itemName = new QTableWidgetItem;
itemName->setText(fileInfo.fileName());
QTableWidgetItem *itemSuffix = new QTableWidgetItem;
itemSuffix->setText(fileInfo.suffix());
QTableWidgetItem *itemSize = new QTableWidgetItem;
itemSize->setText(QString::number(fileInfo.size()));
QTableWidgetItem *itemLine = new QTableWidgetItem;
itemLine->setText(QString::number(lineAll));
QTableWidgetItem *itemCode = new QTableWidgetItem;
itemCode->setText(QString::number(lineCode));
QTableWidgetItem *itemNote = new QTableWidgetItem;
itemNote->setText(QString::number(lineNotes));
QTableWidgetItem *itemBlank = new QTableWidgetItem;
itemBlank->setText(QString::number(lineBlank));
QTableWidgetItem *itemPath = new QTableWidgetItem;
itemPath->setText(fileInfo.filePath());
itemSuffix->setTextAlignment(Qt::AlignCenter);
itemSize->setTextAlignment(Qt::AlignCenter);
itemLine->setTextAlignment(Qt::AlignCenter);
itemCode->setTextAlignment(Qt::AlignCenter);
itemNote->setTextAlignment(Qt::AlignCenter);
itemBlank->setTextAlignment(Qt::AlignCenter);
ui->tableWidget->setItem(i, 0, itemName);
ui->tableWidget->setItem(i, 1, itemSuffix);
ui->tableWidget->setItem(i, 2, itemSize);
ui->tableWidget->setItem(i, 3, itemLine);
ui->tableWidget->setItem(i, 4, itemCode);
ui->tableWidget->setItem(i, 5, itemNote);
ui->tableWidget->setItem(i, 6, itemBlank);
ui->tableWidget->setItem(i, 7, itemPath);
totalBytes += fileInfo.size();
totalLines += lineAll;
totalCodes += lineCode;
totalNotes += lineNotes;
totalBlanks += lineBlank;
if (i % 100 == 0) {
qApp->processEvents();
}
}
//显示统计结果
listFile.clear();
ui->txtCount->setText(QString::number(count));
ui->txtSize->setText(QString::number(totalBytes));
ui->txtRow->setText(QString::number(totalLines));
ui->txtCode->setText(QString::number(totalCodes));
ui->txtNote->setText(QString::number(totalNotes));
ui->txtBlank->setText(QString::number(totalBlanks));
//计算百分比
double percent = 0.0;
//代码行所占百分比
percent = ((double)totalCodes / totalLines) * 100;
ui->labPercentCode->setText(QString("%1%").arg(percent, 5, 'f', 2, QChar(' ')));
//注释行所占百分比
percent = ((double)totalNotes / totalLines) * 100;
ui->labPercentNote->setText(QString("%1%").arg(percent, 5, 'f', 2, QChar(' ')));
//空行所占百分比
percent = ((double)totalBlanks / totalLines) * 100;
ui->labPercentBlank->setText(QString("%1%").arg(percent, 5, 'f', 2, QChar(' ')));
}
void frmCountCode::countCode(const QString &fileName, int &lineCode, int &lineBlank, int &lineNotes)
{
lineCode = lineBlank = lineNotes = 0;
QFile file(fileName);
if (file.open(QFile::ReadOnly)) {
QTextStream out(&file);
QString line;
bool isNote = false;
while (!out.atEnd()) {
line = out.readLine();
//移除前面的空行
if (line.startsWith(" ")) {
line.remove(" ");
}
//判断当前行是否是注释
if (line.startsWith("/*")) {
isNote = true;
}
//注释部分
if (isNote) {
lineNotes++;
} else {
if (line.startsWith("//")) { //注释行
lineNotes++;
} else if (line.isEmpty()) { //空白行
lineBlank++;
} else { //代码行
lineCode++;
}
}
//注释结束
if (line.endsWith("*/")) {
isNote = false;
}
}
}
}
三、效果图

四、开源主页
- 以上作品完整源码下载都在开源主页,会持续不断更新作品数量和质量,欢迎各位关注。
- 本开源项目已经成功升级到V2.0版本,分门别类,图文并茂,保你爽到爆。
- Qt开源武林秘籍开发经验,看完学完,20K起薪,没有找我!
- 国内站点:https://gitee.com/feiyangqingyun/QWidgetDemo
- 国际站点:https://github.com/feiyangqingyun/QWidgetDemo
- 开源秘籍:https://gitee.com/feiyangqingyun/qtkaifajingyan
- 个人主页:https://qtchina.blog.csdn.net/
- 知乎主页:https://www.zhihu.com/people/feiyangqingyun/
Qt开源作品10-代码统计组件的更多相关文章
- Qt开源作品38-无边框窗体方案(无抖动,支持win、linux、mac等系统,侧边半屏顶部全屏)
一 前言 不知道各位程序员有没有遇到过这样一种困惑,好不容易在开源网站找到了类似的想要的项目代码,结果down下来一编译,我勒个去,几百个错误,根本没法用,熟悉的人还好可以直接阅读代码进行修改(有些只 ...
- .NET平台开源项目速览(10)FluentValidation验证组件深入使用(二)
在上一篇文章:.NET平台开源项目速览(6)FluentValidation验证组件介绍与入门(一) 中,给大家初步介绍了一下FluentValidation验证组件的使用情况.文章从构建间的验证器开 ...
- [个人开源]vue-code-view:一个在线编辑、实时预览的代码交互组件
组件简介 vue-code-view是一个基于 vue 2.x.轻量级的代码交互组件,在网页中实时编辑运行代码.预览效果的代码交互组件. 使用此组件, 不论 vue 页面还是 Markdown 文档中 ...
- Github上的一些高分Qt开源项目【多图】
游戏2D地图编辑器: 著名的TileMap编辑器,做2D游戏开发的一定不会陌生. Go 语言的IDE: Go语言的集成开发环境. Clementine Music Player: 功能很完善且跨平台支 ...
- GitHub 和 Gitee 开源免费 10 个超赞后台管理面板,看完惊呆了!
软件工程师在实际项目开发中不可避免需要依赖一些前后端的后台管理系统框架,而不是从零开始一点点的搭建,浪费人力.目前市面上有很多开放源码.且免费的后台管理面板,样式色彩也比较丰富美观. 今天整理 ...
- Twproject Gantt – 开源的 JavaScript 甘特图组件
Twproject Gantt 是一款基于 jQuery 开发的甘特图组件,也可以创建其它图表,例如任务树(Task Trees).内置编辑.缩放和 CSS 皮肤等功能.更重要的是,它是免费开源的. ...
- 微软良心之作——Visual Studio Code 开源免费跨平台代码编辑器
微软良心之作——Visual Studio Code 开源免费跨平台代码编辑器 在 Build 2015 大会上,微软除了发布了 Microsoft Edge 浏览器和新的 Windows 10 预览 ...
- G彩娱乐网【分享】想要开源自己的代码可以参考一下
作为一个开发者,如果你打算开源自己的代码,千万不要忘记,选择一种开源许可证(license). 许多开发者对开源许可证了解很少,不清楚有哪些许可证,应该怎么选择.本文介绍开源许可证的基本知识,主要参考 ...
- 【转载】关于.NET下开源及商业图像处理(PSD)组件
原创]关于.NET下开源及商业图像处理(PSD)组件 阅读目录 1 前言 2 .NET图像处理组件总结 3.相关资源网址 本博客所有文章分类的总目录:http://www.cnblo ...
- Python实现代码统计工具——终极加速篇
Python实现代码统计工具--终极加速篇 声明 本文对于先前系列文章中实现的C/Python代码统计工具(CPLineCounter),通过C扩展接口重写核心算法加以优化,并与网上常见的统计工具做对 ...
随机推荐
- 11 Self-Attention相比较 RNN和LSTM的优缺点
博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https:// ...
- 16收16发ARINC429模块
6通道发送, 16通道接收* 发送通道:每路发送通道FIFO大小为:511 x 32bit(CHR32216/32316) ,缓存256条发送消息(CHR32216-EX/32316-EX)发送FIF ...
- KubeSphere 镜像构建器(S2I)服务证书过期解决方案
目前 KubeSphere 所有 3.x.x 版本,如果开启了 DevOps 模块并使用了镜像构建器功能(S2I)都会遇到证书过期问题. 解决方法 已开启 DevOps 模块 下载这个更新 S2I 服 ...
- 会话层技术-session
会话层技术-session session技术拿下! 一.先整理学习过程中的几个疑惑 cookie和session分别都是怎么创建的? 首先cookie是一个类,它需要java后端开发人员手动创建. ...
- Machine Learning Week_5 Cost Function and BackPropagation
目录 0 Neural Networks: Learning 1 Cost Function and BackPropagation 1.1 Cost Function 1.2 Backpropaga ...
- 《HelloGitHub》第 103 期
兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣.入门级的开源项目. github.com/521xueweihan/HelloG ...
- WebElement的常用属性和方法
WebElement是WebDriver.find_element()方法返回的一个对象,该对象用来描述Web上的一个元素,比如输入框,按钮等.本节介绍WebElement的常用属性和方法. 一.We ...
- Nuxt.js 应用中的 components:dirs 事件钩子详解
title: Nuxt.js 应用中的 components:dirs 事件钩子详解 date: 2024/10/31 updated: 2024/10/31 author: cmdragon exc ...
- isPrimitive:检测数据是不是原始数据
function isPrimitive(value) { return isStatic(value) || typeof value === 'symbol}
- .NET斗鱼直播弹幕客户端(上)
现在直播平台由于弹幕的存在,主播与观众可以更轻松地进行互动,非常受年轻群众的欢迎.斗鱼TV就是一款非常流行的直播平台,弹幕更是非常火爆.看到有不少主播接入弹幕语音播报器.弹幕点歌等模块,这都需要首先连 ...