Python实战之手把手教你写一个带界面的照片按日期归档与清理工具

 更新时间:2025年11月26日 08:31:10   作者:winfredzhang  
这篇文章主要为大家详细介绍了如何将利用 Python 和 wxPython 图形界面库,编写一个自动化的工具,不仅能按拍摄日期自动归档媒体文件,还能在校验成功后安全地将源文件移入回收站,感兴趣的小伙伴可以了解下

前言

为硬盘减负你是否也有这样的烦恼:手机或相机的存储卡满了,里面的照片和视频成千上万,堆在一个文件夹里杂乱无章?想把它们备份到移动硬盘,却发现手动按日期分类太累?备份完了又不敢轻易删除源文件,怕万一没拷过去怎么办?

今天,我们将利用 Python 和 wxPython 图形界面库,编写一个自动化的工具。它不仅能按拍摄日期自动归档媒体文件,还能在校验成功后安全地将源文件移入回收站。

核心功能与技术栈

我们要实现的功能非常明确:

  • GUI 界面:通过日历选择日期,通过文件选择器选择源目录和目标目录。
  • 按日期筛选:自动扫描源文件夹(包括子目录),找出指定日期创建的照片/视频。
  • 自动归档:在目标盘建立 YYYYMMDD 格式的文件夹,并复制文件。
  • 安全清理:复制成功且校验无误后,将源文件移入回收站(而不是直接永久删除)。
  • 防假死:使用多线程处理文件操作,防止界面卡顿。

使用的库:

  • wxPython: 绘制原生风格的图形界面。
  • shutil: 负责文件的高级复制(保留元数据)。
  • os & datetime: 处理文件路径和时间。
  • send2trash: 关键库,用于将文件发送到回收站。
  • threading: 实现后台任务处理。

代码深度剖析

界面布局 (GUI Layout)

我们继承了 wx.Frame 来创建主窗口。布局上使用了 wx.BoxSizer,这是一种弹性盒子布局,能够让界面元素随窗口大小自动调整。

核心控件初始化

self.date_picker = wx.adv.DatePickerCtrl(panel, style=wx.adv.DP_DROPDOWN | wx.adv.DP_SHOWCENTURY)
self.src_picker = wx.DirPickerCtrl(panel, message=“选择源文件夹”)
self.dst_picker = wx.DirPickerCtrl(panel, path=default_path, message=“选择目标文件夹”)

亮点:使用了 DatePickerCtrl,让用户点选日历,而不是手动输入“2023-11-25”,减少了格式错误的可能。

遇到的“坑”:wx.DateTime 类型转换

在编写过程中,我们遇到了一个典型的报错:

TypeError: unsupported operand type(s) for +: ‘sip.enumtype’ and ‘int’

原因分析:wxPython 的较新版本(Phoenix)中,wx_date.Month 属性返回的是一个枚举对象(如 wx.DateTime.Month.Jan),而不是整数。且 wxPython 的月份是从 0 开始(0-11),而 Python 标准库 datetime 需要的是 1-12。

解决方案:我们必须使用 .GetMonth() 方法获取整数值,并手动 +1。

修正后的代码

wx_date = self.date_picker.GetValue()

GetMonth() 返回 0-11,所以需要 +1

target_date = datetime.date(wx_date.GetYear(), wx_date.GetMonth() + 1, wx_date.GetDay())

核心逻辑:遍历与筛选

为了找到深藏在子文件夹里的照片,我们使用了 os.walk()。它可以递归地遍历目录树。

MEDIA_EXTENSIONS = {‘.jpg', ‘.mp4', …} # 定义白名单

for root, dirs, files in os.walk(src_dir):
for file in files:
# 1. 扩展名过滤
if ext.lower() not in MEDIA_EXTENSIONS: continue
    # 2. 日期匹配
    ctime = os.path.getctime(file_path)
    file_date = datetime.date.fromtimestamp(ctime)
    
    if file_date == target_date:
        self.ProcessFile(...)

这里的逻辑非常严谨:只处理白名单内的媒体文件,避免误移动系统文件或文本文件。

数据安全:复制与“后悔药”机制

这是本工具最核心的价值所在。普通脚本用 shutil.move,一旦出错文件可能丢失。我们采用了“复制+校验+放入回收站”的三步走策略。

def ProcessFile(self, src_path, dst_folder, filename):
# … 省略重名处理 …

# 第一步:复制 (copy2 保留拍摄时间等元数据)
shutil.copy2(src_path, dst_path) 

# 第二步:校验
# 确保目标文件存在,且大小与源文件一致
if os.path.exists(dst_path) and os.path.getsize(dst_path) == os.path.getsize(src_path):
    # 第三步:安全删除 (放入回收站)
    send2trash(src_path)
else:
    self.Log("错误:复制校验失败,未删除源文件")

使用 send2trash 是为了给用户一剂“后悔药”。万一你选错了日期或者程序逻辑有误,文件只是在回收站里,随时可以还原,数据安全大于一切。

用户体验:多线程防假死

如果直接在按钮点击事件里运行上述循环,处理几百个视频时,界面会直接卡死(显示“未响应”)。为了解决这个问题,我们引入了 threading。

def OnStartBackup(self, event):
# 禁用按钮
self.btn_start.Disable()
# 开启子线程
thread = threading.Thread(target=self.RunBackupLogic, args=(…))
thread.start()
def Log(self, message):
# 使用 wx.CallAfter 确保在主线程更新 UI,防止崩溃
wx.CallAfter(self.log_ctrl.AppendText, f"…{message}\n")

注意:子线程不能直接操作界面控件(如 TextCtrl),必须使用 wx.CallAfter 将更新指令发送回主UI线程,这是 GUI 编程的金科玉律。

运行效果

程序启动后,只需三步:

  • 选择你要整理的那一天的日期(例如某次旅游的日期)。
  • 选择存放混乱照片的源文件夹。
  • 选择移动硬盘作为目标文件夹。

点击“开始”,你会在日志框看到一行行滚动的记录:

[10:00:01] 成功备份并清理: IMG_2023.JPG
[10:00:02] 发现重名,重命名为: VIDEO_001_1.MP4

完成后,程序目录还会生成一个 backup_history.txt,记录你的备份流水。

运行结果

到此这篇关于Python实战之手把手教你写一个带界面的照片按日期归档与清理工具的文章就介绍到这了,更多相关Python文件按日期归档内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • OpenCV半小时掌握基本操作之图像处理

    OpenCV半小时掌握基本操作之图像处理

    这篇文章主要介绍了OpenCV基本操作之图像处理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • Python编程入门指南之函数

    Python编程入门指南之函数

    这篇文章主要为大家介绍了Python编程之函数,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • 使用Python的Twisted框架编写简单的网络客户端

    使用Python的Twisted框架编写简单的网络客户端

    这篇文章主要介绍了使用Python的Twisted框架编写简单的网络客户端,翻译自Twisted文档,包括一个简单的IRC客户端的实现,需要的朋友可以参考下
    2015-04-04
  • python二维码操作:对QRCode和MyQR入门详解

    python二维码操作:对QRCode和MyQR入门详解

    今天小编就为大家分享一篇python二维码操作:对QRCode和MyQR入门详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-06-06
  • Scrapy使用的基本流程与实例讲解

    Scrapy使用的基本流程与实例讲解

    今天小编就为大家分享一篇关于Scrapy使用的基本流程与实例讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-10-10
  • 解决Pytorch中的神坑:关于model.eval的问题

    解决Pytorch中的神坑:关于model.eval的问题

    这篇文章主要介绍了解决Pytorch中的神坑:关于model.eval的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-05-05
  • python使用SMTP发送qq或sina邮件

    python使用SMTP发送qq或sina邮件

    这篇文章主要为大家详细介绍了python使用SMTP发送qq或sina邮件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • 使用Python构建MCP服务器的详细配置步骤

    使用Python构建MCP服务器的详细配置步骤

    模型控制协议(MCP)是一种专为实现AI代理与工具解耦而设计的通信协议,为AI驱动应用程序的开发提供了高度的灵活性和模块化架构,本文将详细介绍MCP服务器的构建过程,包括工具函数的注册、配置以及与Claude Desktop等AI代理的集成,需要的朋友可以参考下
    2025-06-06
  • pytest实战技巧之参数化基本用法和多种方式

    pytest实战技巧之参数化基本用法和多种方式

    本文介绍了pytest参数化的基本用法和多种方式,帮助读者更好地使用这个功能,同时,还介绍了一些高级技巧,如动态生成参数名称、参数化的组合和动态生成参数化装饰器,帮助读者更灵活地使用参数化,感兴趣的朋友参考下吧
    2023-12-12
  • Python动态导入模块的方法实例分析

    Python动态导入模块的方法实例分析

    这篇文章主要介绍了Python动态导入模块的方法,结合实例形式较为详细的分析了Python动态导入系统模块、自定义模块以及模块列表的相关操作技巧,需要的朋友可以参考下
    2018-06-06

最新评论