基于Python+PyQt5开发的Windows磁盘分析与清理工具

 更新时间:2026年07月23日 08:56:15   作者:donoot  
SysDriMan是一款基于Python和PyQt5的免费开源Windows磁盘分析与清理工具,提供磁盘空间可视化、大文件管理、软件卸载和垃圾清理等功能,支持多线程扫描和流光进度条,帮你快速释放磁盘空间,解决电脑卡顿问题,需要的朋友可以参考下

项目概述

SysDriMan 是一款基于 Python 和 PyQt5 开发的 Windows 磁盘分析与清理工具,旨在帮助用户快速了解磁盘空间使用情况,管理大文件和已安装软件,清理系统垃圾文件。

项目地址:https://github.com/donoot/SysDriMan

功能特性

1. 磁盘空间分析

  • 饼图可视化:直观展示磁盘空间分布情况
  • 递归浏览:双击饼图扇区可进入子目录查看详细分布
  • 空间信息显示:实时显示总空间、已用空间、剩余空间

2. 大文件管理

  • 自动扫描:扫描并列出大于指定阈值的大文件
  • 文件详情:显示文件路径、大小、修改时间、创建时间
  • 列宽可调:表格列宽支持鼠标拖动调节

3. 已安装软件管理

  • 注册表读取:从 Windows 注册表读取所有已安装软件
  • 快速操作:右键菜单支持卸载和修改软件

4. 垃圾文件清理

  • 自动扫描:扫描系统临时目录、回收站等常见垃圾位置
  • 一键清理:支持批量清理选中的垃圾文件(移至回收站)

5. 流光进度条

  • 滚动渐变:参考经典工具"溯雪"的流光效果
  • 实时百分比:中间显示扫描进度百分比

技术架构设计

整体架构

​编辑模块划分

模块职责文件
主窗口UI 界面构建和功能集成main.py
工具函数管理员权限检查、文件大小格式化utils.py
扫描线程后台磁盘扫描、多线程并行处理scan_thread.py
软件管理注册表读取、软件卸载software_manager.py
垃圾清理垃圾文件扫描、清理garbage_cleaner.py

核心技术实现

1. 多线程并行扫描

问题背景:磁盘扫描是一个耗时操作,如果在主线程中执行会导致 UI 卡顿。

解决方案:使用 Python threading 模块结合 Qt 的 QThread 实现多线程并行扫描。

class ScanWorker(threading.Thread):
    """扫描工作线程类"""
    def __init__(self, task_queue, result_queue, size_threshold, stop_event):
        super().__init__()
        self.task_queue = task_queue
        self.result_queue = result_queue
        self.size_threshold = size_threshold
        self.stop_event = stop_event
​
    def run(self):
        while not self.stop_event.is_set():
            try:
                dirpath, dirnames, filenames = self.task_queue.get(timeout=1)
            except:
                break
            dir_size = 0
            big_files = []
            for f in filenames:
                try:
                    fp = os.path.join(dirpath, f)
                    if os.path.isfile(fp):
                        st = os.stat(fp)
                        size = st.st_size
                        dir_size += size
                        if size >= self.size_threshold:
                            big_files.append((fp, size, ...))
                except (PermissionError, OSError):
                    continue
            self.result_queue.put((dirpath, dir_size, big_files))
            self.task_queue.task_done()

关键设计

  • 使用 Queue 实现任务分发和结果收集
  • 多个 ScanWorker 线程并行处理目录扫描
  • 通过 stop_event 实现优雅停止
  • 使用 Qt 信号机制向主线程传递进度

2. 流光进度条实现

问题背景:用户希望进度条具有流动的视觉效果,类似于经典工具"溯雪"中的流光效果。

解决方案:使用 QTimer 定时更新 QProgressBar 的样式表,实现滚动渐变效果。

def setup_flow_progress_style(self):
    """设置流光进度条样式"""
    self.flow_gradient_pos = 0
    self.flow_timer = QTimer(self)
    self.flow_timer.timeout.connect(self.update_flow_animation)
    base_style = """
    QProgressBar {
        border: 1px solid #666666;
        border-radius: 4px;
        background: qlineargradient(x1:0, y1:0, x2:0, y2:1, 
            stop:0 #4a4a4a, stop:0.5 #3d3d3d, stop:1 #333333);
        text-align: center;
        color: #00ffff;
        font-weight: bold;
        font-size: 12px;
    }
    QProgressBar::chunk {
        border-radius: 3px;
        margin: 1px;
    }
    """
    self.progress_bar.setStyleSheet(base_style)
​
def update_flow_animation(self):
    """更新流光动画"""
    self.flow_gradient_pos = (self.flow_gradient_pos + 1) % 100
    p = self.flow_gradient_pos / 100.0
    style = f"""
    QProgressBar::chunk {{
        background: qlineargradient(x1:0, y1:0, x2:1, y2:0, 
            stop:{(p - 0.3) % 1} transparent, 
            stop:{(p - 0.2) % 1} rgba(0, 200, 255, 0.3), 
            stop:{(p - 0.1) % 1} rgba(0, 220, 255, 0.6), 
            stop:{p % 1} rgba(0, 255, 255, 1), 
            stop:{(p + 0.1) % 1} rgba(0, 220, 255, 0.6), 
            stop:{(p + 0.2) % 1} rgba(0, 200, 255, 0.3), 
            stop:{(p + 0.3) % 1} transparent);
    }}
    """
    self.progress_bar.setStyleSheet(style)

关键设计

  • 使用 rgba 颜色值实现透明度渐变
  • 通过取模运算实现无缝循环
  • 50ms 定时器间隔保证动画流畅

3. Matplotlib 饼图嵌入 Qt 界面

问题背景:需要在 PyQt5 界面中嵌入交互式饼图,支持双击进入子目录。

解决方案:使用 FigureCanvasQTAgg 将 Matplotlib 图表嵌入 Qt 界面,并绑定鼠标事件。

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
​
class MainWindow(QMainWindow):
    def __init__(self):
        ...
        self.fig = Figure(figsize=(5, 5))
        self.canvas = FigureCanvas(self.fig)
        self.left_layout.addWidget(self.canvas)
        self.canvas.mpl_connect('button_press_event', self.on_pie_click)
    def on_pie_click(self, event):
        """处理饼图双击事件"""
        if event.dblclick and hasattr(self, 'wedges'):
            for i, wedge in enumerate(self.wedges):
                if wedge.contains(event)[0]:
                    label = self.pie_labels[i]
                    if label == '其他目录':
                        return
                    new_path = os.path.join(self.current_path, label)
                    if os.path.isdir(new_path):
                        self.path_history.append(self.current_path)
                        self.current_path = new_path
                        self.update_pie_chart()
                    break

关键设计

  • 使用 FigureCanvasQTAgg 作为 Qt 控件
  • 通过 mpl_connect 绑定鼠标事件
  • 使用 wedge.contains(event) 判断点击位置
  • 维护路径历史支持返回上层

4. 管理员权限自动提升

问题背景:访问系统目录和注册表需要管理员权限,普通用户运行会遇到权限不足问题。

解决方案:在程序启动时检查权限,若无管理员权限则自动提升。

import ctypes
import sys
​
def is_admin():
    """检查当前进程是否以管理员身份运行"""
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False
​
def run_as_admin():
    """以管理员身份重新启动程序"""
    if sys.platform == 'win32':
        script = os.path.abspath(sys.argv[0])
        params = ' '.join(['"' + arg + '"' for arg in sys.argv[1:]])
        ctypes.windll.shell32.ShellExecuteW(
            None, "runas", sys.executable, 
            f'"{script}" {params}', None, 1
        )
​
if __name__ == "__main__":
    if not is_admin():
        run_as_admin()
        sys.exit(0)
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

关键设计

  • 使用 IsUserAnAdmin() 检查权限
  • 使用 ShellExecuteWrunas 方式启动
  • 保留命令行参数传递

5. 中文字体配置

问题背景:Matplotlib 默认不支持中文,中文标签会显示为方块或乱码。

解决方案:检测系统可用字体并配置 Matplotlib 使用中文字体。

import matplotlib.font_manager as fm
​
def setup_matplotlib_font():
    """设置matplotlib中文字体"""
    available_fonts = [f.name for f in fm.fontManager.ttflist]
    preferred_fonts = [
        'SimHei', 'Microsoft YaHei', 'SimSun', 'KaiTi',
        'Heiti SC', 'STHeiti'
    ]
    selected_font = None
    for font in preferred_fonts:
        if font in available_fonts:
            selected_font = font
            break
    if selected_font:
        matplotlib.rcParams['font.sans-serif'] = [selected_font]
        matplotlib.rcParams['font.family'] = 'sans-serif'
    matplotlib.rcParams['axes.unicode_minus'] = False
​
setup_matplotlib_font()

关键设计

  • 枚举系统可用字体列表
  • 按优先级选择最合适的中文字体
  • 关闭 Unicode 负号替换

遇到的问题与解决方案

问题 1:QProgressBar 样式频繁更新导致闪烁

现象:每次更新进度条样式表时,界面会出现短暂闪烁。

原因:频繁调用 setStyleSheet 会触发控件重绘。

解决方案

  • 初始化时设置基础样式,动画更新时只修改 ::chunk 部分
  • 使用 QTimer 控制更新频率(50ms)

问题 2:多线程资源竞争

现象:多个线程同时写入结果字典时可能出现数据不一致。

原因:Python 的字典不是线程安全的。

解决方案

  • 使用 Queue 收集结果,在主线程中汇总
  • 避免多个线程直接修改共享数据结构

问题 3:Windows 控制台中文乱码

现象:程序输出的中文路径在控制台显示为乱码。

原因:Windows 控制台默认使用 GBK 编码,而 Python 使用 UTF-8。

解决方案

if sys.platform == 'win32':
    ctypes.windll.kernel32.SetConsoleCP(65001)
    ctypes.windll.kernel32.SetConsoleOutputCP(65001)
os.environ['PYTHONUTF8'] = '1'

问题 4:Matplotlib 饼图标签重叠

现象:当目录名称较长时,饼图标签会重叠。

解决方案

  • 设置 labeldistance=1.15 增加标签距离
  • 使用较小的字体大小(8-10pt)
  • 限制显示的目录数量(前 10 个 + 其他)

项目运行

环境要求

依赖安装命令
PyQt5pip install PyQt5
Matplotlibpip install matplotlib
psutilpip install psutil
send2trashpip install send2trash

启动方式

cd src
python main.py

注意:程序会自动检查管理员权限,若无权限会弹出 UAC 提示。

总结与展望

已实现功能

  1. ✅ 磁盘空间分析与可视化
  2. ✅ 多线程并行扫描
  3. ✅ 流光进度条动画
  4. ✅ 大文件管理
  5. ✅ 软件管理(注册表读取、卸载)
  6. ✅ 垃圾文件清理
  7. ✅ 管理员权限自动提升
  8. ✅ 中文路径支持

未来计划

  1. 🔲 添加磁盘健康检测功能
  2. 🔲 支持导出分析报告(PDF/Excel)
  3. 🔲 添加文件类型统计
  4. 🔲 优化扫描算法,支持增量扫描
  5. 🔲 添加快捷键支持
  6. 🔲 支持深色/浅色主题切换

结语

SysDriMan 项目展示了如何使用 PyQt5 构建功能完善的桌面应用,涵盖了多线程编程、数据可视化、系统权限管理等多个技术要点。希望本文能对正在学习 PyQt5 开发的小伙伴有所帮助!

以上就是基于Python和PyQt5开发的Windows磁盘分析与清理工具的详细内容,更多关于PyQt5 Windows磁盘分析与清理工具的资料请关注脚本之家其它相关文章!

相关文章

  • 基于pytorch实现对图片进行数据增强

    基于pytorch实现对图片进行数据增强

    图像数据增强是一种在训练机器学习和深度学习模型时常用的策略,尤其是在计算机视觉领域,具体而言,它通过创建和原始图像稍有不同的新图像来扩大训练集,本文给大家介绍了如何基于pytorch实现对图片进行数据增强,需要的朋友可以参考下
    2024-01-01
  • Python numpy之线性代数与随机漫步

    Python numpy之线性代数与随机漫步

    这篇文章主要介绍了Python numpy之线性代数与随机漫步,线性代数,矩阵计算,优化与内存;比如矩阵乘法,分解,行列式等数学知识,是所有数组类库的重要组成部分
    2022-07-07
  • python3操作mysql数据库的方法

    python3操作mysql数据库的方法

    这篇文章主要介绍了python3操作mysql数据库的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • PyCharm添加python库的方法步骤

    PyCharm添加python库的方法步骤

    在使用PyCharm过程中,有时候需要添加需要的Python扩展库,本文主要介绍了PyCharm添加python库的方法步骤,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • pyside写ui界面入门示例

    pyside写ui界面入门示例

    PySide 是一个python绑定的跨平台GUI Qt库。目前,支持Python的Qt库有两个PyQt和PySide。下面写一个简单的hello程序学习他的使用方法
    2014-01-01
  • Python 自动控制原理 control的详细解说

    Python 自动控制原理 control的详细解说

    这篇文章主要介绍了Python自动控制原理control的详细解说,文章围绕主题展开对Python control的介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-07-07
  • 进一步探究Python的装饰器的运用

    进一步探究Python的装饰器的运用

    这篇文章主要介绍了更为深入的Python的装饰器的运用,Python的装饰器是Python学习进阶当中的重要知识点,需要的朋友可以参考下
    2015-05-05
  • Python获取字典变量内存占用的四种方法

    Python获取字典变量内存占用的四种方法

    本文主要介绍了Python获取字典变量内存占用的四种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-09-09
  • Python实现遗传算法(虚拟机中运行)

    Python实现遗传算法(虚拟机中运行)

    遗传算法(GA)是最早由美国Holland教授提出的一种基于自然界的“适者生存,优胜劣汰”基本法则的智能搜索算法。本文主要介绍了如何通过Python实现遗传算法,感兴趣的同学可以看一看
    2021-11-11
  • 解决运行出现''dict'' object has no attribute ''has_key''问题

    解决运行出现''dict'' object has no attribute ''has_key''问题

    这篇文章主要介绍了快速解决出现class object has no attribute ' functiong' or 'var'问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07

最新评论