一、前言

代码行数统计主要用来统计项目中的所有文件的代码行数,其中包括空行、注释行、代码行,可以指定过滤拓展名,比如只想统计.cpp的文件,也可以指定文件或者指定目录进行统计。写完这个工具第一件事情就是统计了一下自己写过的最大的项目大概多少行代码,看下是不是传说中的一行代码一块钱,这个最大的项目从2010年开始的,到现在差不多快10年了,是自己在现在公司写过的最大的项目,一直在升级更新完善,途中重构过两次,大的结构改动,统计了下好像有15W行左右的代码,纯代码大概在10W,其余是空行和注释行,着实把自己吓了一跳,还算是中型项目了,然后又统计了下自定义控件的所有代码,我勒个去,总代码23W行,纯代码17W行呢,哎呀我去!

主要功能:

  1. 可分别统计代码行/空行/注释行
  2. 支持指定过滤拓展名
  3. 支持指定文件或者指定目录进行统计
  4. 分步显示统计结果,不卡主界面
  5. 分别展示每个统计过的文件的大小/总行数/代码行数等

二、代码思路

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起薪,没有找我!
  1. 国内站点:https://gitee.com/feiyangqingyun/QWidgetDemo
  2. 国际站点:https://github.com/feiyangqingyun/QWidgetDemo
  3. 开源秘籍:https://gitee.com/feiyangqingyun/qtkaifajingyan
  4. 个人主页:https://qtchina.blog.csdn.net/
  5. 知乎主页:https://www.zhihu.com/people/feiyangqingyun/

Qt开源作品10-代码统计组件的更多相关文章

  1. Qt开源作品38-无边框窗体方案(无抖动,支持win、linux、mac等系统,侧边半屏顶部全屏)

    一 前言 不知道各位程序员有没有遇到过这样一种困惑,好不容易在开源网站找到了类似的想要的项目代码,结果down下来一编译,我勒个去,几百个错误,根本没法用,熟悉的人还好可以直接阅读代码进行修改(有些只 ...

  2. .NET平台开源项目速览(10)FluentValidation验证组件深入使用(二)

    在上一篇文章:.NET平台开源项目速览(6)FluentValidation验证组件介绍与入门(一) 中,给大家初步介绍了一下FluentValidation验证组件的使用情况.文章从构建间的验证器开 ...

  3. [个人开源]vue-code-view:一个在线编辑、实时预览的代码交互组件

    组件简介 vue-code-view是一个基于 vue 2.x.轻量级的代码交互组件,在网页中实时编辑运行代码.预览效果的代码交互组件. 使用此组件, 不论 vue 页面还是 Markdown 文档中 ...

  4. Github上的一些高分Qt开源项目【多图】

    游戏2D地图编辑器: 著名的TileMap编辑器,做2D游戏开发的一定不会陌生. Go 语言的IDE: Go语言的集成开发环境. Clementine Music Player: 功能很完善且跨平台支 ...

  5. GitHub 和 Gitee 开源免费 10 个超赞后台管理面板,看完惊呆了!

      软件工程师在实际项目开发中不可避免需要依赖一些前后端的后台管理系统框架,而不是从零开始一点点的搭建,浪费人力.目前市面上有很多开放源码.且免费的后台管理面板,样式色彩也比较丰富美观.   今天整理 ...

  6. Twproject Gantt – 开源的 JavaScript 甘特图组件

    Twproject Gantt 是一款基于 jQuery 开发的甘特图组件,也可以创建其它图表,例如任务树(Task Trees).内置编辑.缩放和 CSS 皮肤等功能.更重要的是,它是免费开源的. ...

  7. 微软良心之作——Visual Studio Code 开源免费跨平台代码编辑器

    微软良心之作——Visual Studio Code 开源免费跨平台代码编辑器 在 Build 2015 大会上,微软除了发布了 Microsoft Edge 浏览器和新的 Windows 10 预览 ...

  8. G彩娱乐网【分享】想要开源自己的代码可以参考一下

    作为一个开发者,如果你打算开源自己的代码,千万不要忘记,选择一种开源许可证(license). 许多开发者对开源许可证了解很少,不清楚有哪些许可证,应该怎么选择.本文介绍开源许可证的基本知识,主要参考 ...

  9. 【转载】关于.NET下开源及商业图像处理(PSD)组件

    原创]关于.NET下开源及商业图像处理(PSD)组件   阅读目录 1 前言 2 .NET图像处理组件总结 3.相关资源网址        本博客所有文章分类的总目录:http://www.cnblo ...

  10. Python实现代码统计工具——终极加速篇

    Python实现代码统计工具--终极加速篇 声明 本文对于先前系列文章中实现的C/Python代码统计工具(CPLineCounter),通过C扩展接口重写核心算法加以优化,并与网上常见的统计工具做对 ...

随机推荐

  1. kotlin更多语言结构——>相等性

    Kotlin 中有两种类型的相等性: - 结构相等(用 equals() 检测); - 引用相等(两个引用指向同一对象).   结构相等 结构相等由 ==(以及其否定形式 !=)操作判断.按照惯例,像 ...

  2. 快速理解和使用stream流

    数据量越大,硬件内核数越多,stream流相比传统for循环速度越快. 原因是stream流是可以并行处理的. 如果要使用stream流,可以直接用flatmap把外层嵌套扁平化,只留下自己需要处理的 ...

  3. c++11大括号初始化

    C++11可以将{}初始化器用于任何类型(可以用等号,也可以不用) 数组.集合初始化 在C++11中,集合(列表)的初始化已经成为C++的一个基本功能,被称为"初始化列表": // ...

  4. 什么是APP原生开发

    什么是APP原生开发?原生App实际上是一种基于智能手机本地操作系统如Android.IOS并且使用原生程序编写运行的第三方移动应用程序.开发原生App软件需要针对不同智能手机的操作系统来选择不同的A ...

  5. API和SDK的区别

    API 和 SDK 有以下区别: 定义与功能: API(应用程序编程接口):是一组定义了软件组件之间交互规范的接口,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而无需访问源码或 ...

  6. 深度学习入门笔记——DataLoader的使用

    如何使用数据集DataSet? 在介绍DataLoader之前,需要先了解数据集DataSet的使用.Pytorch中集成了很多已经处理好的数据集,在pytorch的torchvision.torch ...

  7. Expo上手

    RN中文网:https://reactnative.cn/docs/next/native-modules-android RN路由:https://reactnavigation.org/docs/ ...

  8. 3.1 Linux文件系统的层次结构

    通过学习<Linux一切皆文件>一节我们知道,平时打交道的都是文件,那么,应该如何找到它们呢?很简单,在 Linux 操作系统中,所有的文件和目录都被组织成以一个根节点"/&qu ...

  9. 为政务单位免费提供IP地址https证书—JoySSL

    JoySSL作为知名的证书颁发机构(CA),确实为政务单位提供了IP地址HTTPS证书的免费测试证书服务.以下是对此服务的详细介绍: 一.证书类型与特点 证书类型:JoySSL为政务单位提供了专为IP ...

  10. ABC240Ex Sequence of Substrings

    ABC240Ex Sequence of Substrings LIS 的好题改编. 约定 \(S(l,r)\) 为字符串 \(s\) 中第 \(l\) 位到底 \(r\)​ 位. \(S(l,r)& ...