用Python做一个文件夹整理工具
文章目录
- 简介
- 文件夹对话框
- 文件映射组件
- 完整组件
简介
我们的目的是做一个像下面这样的工具,前面两个输入框,用于输入源路径和目标路径,下面的图片、视频、音乐表示在目标路径中创建的文件夹,后面的文件后缀,表示将这类文件移动到对应的文件夹中,加减号可以新增或删除文件夹。

文件夹对话框
第一步,实现源路径和目标路径的输入输出,从而需要自定义一个组件,代码如下,其及具体实现逻辑,可以参考:自定义文件选择按钮
import tkinter as tk
import tkinter.ttk as ttk
from tkinter.filedialog import (askopenfilename,askopenfilenames, askdirectory, asksaveasfilename)
from tkinter.colorchooser import askcolorclass DialogButton(ttk.Frame):def __init__(self, master, height, widthL, widthR, logtype, label=None, text=None, frmDct={}, btnDct={}, enyDct={}, logDct={}):w = widthL + widthRsuper().__init__(master, height=height, width = w, **frmDct)self.pack(fill=tk.X)self.text = tk.StringVar() if not text else textttk.Entry(self, width=widthL, textvariable=self.text, **enyDct).pack(side=tk.LEFT, fill = tk.X, expand=True)ttk.Button(self, width=widthR, text=self.setLabel(logtype, label),command = self.Click, **btnDct).pack(side=tk.RIGHT, padx=5)self.logtype = logtypeself.logDct = logDctdef setLabel(self, key, label=None):if label:return labellabelDct = {"文件" : "选择文件","文件夹" : "选择路径","多文件" : "选择多个文件","保存" : "存储路径","颜色" : "选择颜色",}return labelDct[key]def Click(self):typeDct = {"文件" : askopenfilename,"文件夹": askdirectory,"多文件": askopenfilenames,"保存" : asksaveasfilename,"颜色" : askcolor,}text = typeDct[self.logtype](**self.logDct)if self.logtype == "颜色":text = text[1]self.text.set(text)def get(self):return self.text.get()def set(self, txt):self.text.set(txt)
文件映射组件
关于文件夹整理这个功能,此前其实做过无图形界面的版本:
Python整理下载文件夹,第一步自然是做一个文件映射字典,
F_DCT = {"图片" : [".jpg", ".png", ".jpeg", ".gif"],"视频" : [".mp4", ".mkv"],"音乐" : [".mp3", ".wav"],"文档" : [".pdf"], "文献" : [".caj"],"文本" : [".csv", ".txt"],"源码" : [".py", ".c", ".cpp", ".php"],"office": [".docx",".xlsx", ".pptx", ".doc", ".ppt", ".xls"],"压缩包": [".zip", ".tgz", ".rar", ".tar", ".7z", ".gz"],"安装包": [".msi", ".exe"],
}
然后就是工具的核心内容,文件映射组件,主要由左右两部分组成,左侧是文件夹名,右侧是对应的文件后缀。从这两个子组件出发,可以为其设置初始化参数以及方法。先看源码,再逐段解析
import tkinter as tk
import tkinter.ttk as ttk
from ctrls import DialogButton
import os
import shutil
pJoin = os.path.join
pExist = os.path.existsfrom pathlib import Pathclass ExFolder(ttk.Frame):def __init__(self, master, folder=None, ex=None, dst=None, **options):super().__init__(master, **options)self.pack()self.folder = tk.StringVar()if folder : self.setFolder(folder)self.ex = tk.StringVar()if ex : self.setEx(ex)self.setDst(dst)self.initWidgets()def initWidgets(self):ttk.Entry(self, textvariable=self.folder, width=10).pack(side=tk.LEFT, padx=2) ttk.Entry(self, textvariable=self.ex).pack(side=tk.LEFT, fill=tk.X, expand=True)def getFolder(self):return self.folder.get()def setFolder(self, f):self.folder.set(f)def getEx(self):exs = self.ex.get().split(",")for i in range(len(exs)):exs[i] = exs[i].strip()return exsdef setEx(self, exs):if type(exs)==list:exs = ', '.join([ex.strip() for ex in exs])self.ex.set(exs)def mvFile(self, src):try:shutil.move(src, self.dst)except Exception as e:self.err = print(e)# 设置目标文件夹def setDst(self, dst):if not dst:self.dst = Nonereturnself.dst = pJoin(dst, self.getFolder())if not pExist(self.dst):os.makedirs(self.dst)self.errs = {}
首先,folder和ex分别是左右两个组件对应的可变文本,为了便于更新和调用,类中设计了两组、四对便携方法getFolder, setFolder和getEx和setEx。由于Folder中的内容就是文件夹本身,所以设置和读取方法仅仅是StringVar的二次封装,而ex中的内容则不然,需要对文本进行分割,并且实现字符串到列表的转换。
mvFile和setDst是组件的核心功能,分别用于设置目标路径并移动。之所以为目标文件夹设置安排了一个独立方法,是因为目标文件夹不一定存在,可能涉及到递归创建的过程。
完整组件
最后,是整个组件的布局,源码如下,其中撤销功能并未实现。
class FolderTools(ttk.Frame):def __init__(self, master, fDct=F_DCT, **options):super().__init__(master, **options)self.pack()self.fDct = fDctself.initWidgets()self.fEnys = []self.exEnys = []def setDct(self, fDct):self.fDct = fDctself.exDct = {}for k,v in self.fDct.items():exDct.update({ex:k for ex in v})def initWidgets(self):self.exForders = []pDct = dict(side=tk.TOP, expand=True, fill=tk.X)self.srcFolder = DialogButton(self, 5, 25, 8, "文件夹", label="源路径")self.srcFolder.pack(**pDct)self.dstFolder = DialogButton(self, 5, 25, 8, "文件夹", label="目标路径")self.dstFolder.pack(**pDct)btns = ttk.Frame(self)btns.pack(**pDct)ttk.Button(btns, text="➕ ", command=self.btnAddFolder).grid(row=0,column=0)ttk.Button(btns, text="➖", command=self.btnDelFolder).grid(row=0,column=1)ttk.Button(btns, text="移动", command=self.btnMove).grid(row=0,column=2)ttk.Button(btns, text="撤销", command=self.btnMove).grid(row=0,column=3)self.exFrm = ttk.LabelFrame(self, text="文件夹映射表")self.exFrm.pack(**pDct)for k, v in self.fDct.items():self.addFolders(self.exFrm, k, v)def btnAddFolder(self):self.addFolders(self.exFrm, None, None)def addFolders(self, frm, folder, exs):ef = ExFolder(frm, folder, exs)ef.pack(side=tk.TOP, expand=True, fill=tk.X, padx=2, pady=1)self.exForders.append(ef)def btnDelFolder(self):if len(self.exForders) == 0: returnself.exForders[-1].pack_forget()del self.exForders[-1]def setExDct(self):self.exDct = {}for ef in self.exForders:self.exDct.update({key:ef for key in ef.getEx()})def btnMove(self):src = self.srcFolder.get()dst = self.dstFolder.get()if dst=="": dst = src# 设置后缀映射字典 ex:ExFolderexDct = {}for ef in self.exForders:exDct.update({ex:ef for ex in ef.getEx()})ef.setDst(dst) # 设置目标文件夹files = os.listdir(src)for f in files:p = pJoin(src, f)ex = Path(p).suffix.lower()if ex in exDct:exDct[ex].mvFile(p)
三个已经实现的功能按钮,➕用于新增一个文件夹映射组件,➖则移除最后一个映射组件。移除组件时需要注意,不仅仅要把组件解绑,还要把组件对应的实例删掉。
核心功能被绑定在移动按钮上,首先读取源路径和目标路径,如果目标路径未输入,就在源路径下工作。
接下来,将文件映射组件重新拆解为映射字典,最后调用对应组件的mvFile方法,实现所有文件的移动。
相关文章:
用Python做一个文件夹整理工具
文章目录 简介文件夹对话框文件映射组件完整组件 简介 我们的目的是做一个像下面这样的工具,前面两个输入框,用于输入源路径和目标路径,下面的图片、视频、音乐表示在目标路径中创建的文件夹,后面的文件后缀,表示将这…...
Tortoise SVN 察看本地缓存密码
1、打开设置(Settings) 2、查看保存的数据 3、打开鉴权数据 4、查看密码 CTRLSHIFT双击表格,就会出现一列密码列 (我的是Mac PD虚拟Win11,CTRLSHIFTOPTION双击表格) 原文见这里: Recover SVN …...
MSP430F5529晶振配置
MSP430(F5529)相比MSP430(F149)来讲,功能更加强大。 UCS简介 MSP430F5XX/MSP430F6XX系列器件的UCS包含有五种时钟源,依次是:XT1CLK、VLOCLK、REFOCLK、DCOCLK和XT2CLK。这五种时钟的详细介绍请参考该系列芯片的指导手册,其中XT1C…...
[架构之路-237]:目标系统 - 纵向分层 - 网络通信 - DNS的递归查询和迭代查询
目录 一、DNS协议与DNS系统架构 1.1 什么是DNS协议 1.2 为什么需要DNS协议 1.3 DNS系统架构 二、DNS系统的查询方式 2.1 递归与迭代的比较 2.2 DNS递归查询 2.3 DNS迭代查询 一、DNS协议与DNS系统架构 1.1 什么是DNS协议 DNS(Domain Name Systemÿ…...
vue2 集成 Onlyoffice
缘起于进行了一次在线 Office 解决方案的调研,对比了 Office365、可道云、WPS Office、PageOffice 等厂商,最终敲定了使用 Onlyoffice,故整理了一份 Onlyoffice 从零开始系列教程,这是第一篇。 一、Onlyoffice 是什么?…...
天锐绿盾透明加密、半透明加密、智能加密这三种不同加密模式的区别和适用场景——@德人合科技-公司内部核心文件数据、资料防止外泄系统
由于企事业单位海量的内部数据存储情况复杂,且不同公司、不同部门对于文件加密的需求各不相同,单一的加密系统无法满足多样化的加密需求。天锐绿盾企业加密系统提供多种不同的加密模式,包括透明加密、半透明加密和智能加密,用户可…...
六、DHCP实验
拓扑图: DHCP协议,给定一个ip范围使其自动给终端分配IP,提高了IP分配的效率 首先对PC设备选择DHCP分配ip 首先先对路由器的下端配置网关的ip 创建地址池,通过globle的方式实现DHCP ip pool 地址池名称 之后设置地址池的网关地址…...
N沟道场效应管 FDA69N25深度图解 工作原理应用
深力科推荐一款 FDA69N25是高压 MOSFET产品,基于平面条形和 DMOS 技术。 该 MOSFET 产品专用于降低通态电阻,并提供更好的开关性能和更高的雪崩能量强度。 该器件系列适用于开关电源转换器应用,如功率因数校正(PFC)、…...
Python爬虫入门教程
文章目录: 一:Python基础 二:爬虫须知 1.流程 2.遵守规则 三:HTTP请求和响应 1.相关定义 2.HTTP请求响应 2.1 完整的HTTP请求 2.2 完整的HTTP响应 3.Requests库 四:HTML 1.HTML网页结构 2.常用标 参考&…...
使用正则前瞻检查密码强度
使用正则前瞻检查密码强度 题目要求 要求密码必须包含大小写字母,并且至少包含 $,_. 中的一个特殊字符。 在这道题中,我们可以使用正则表达式的前瞻运算来实现。 const reg /^(?.*\d)(?.*[a-z])(?.*[A-Z])(?.*[$,_.])[\da-zA-Z$,_.]{6,12}/;con…...
react+ts手写cron表达式转换组件
前言 最近在写的一个分布式调度系统,后端同学需要让我传入cron表达式,给调度接口传参。我去了学习了解了cron表达式的用法,发现有3个通用的表达式刚好符合我们的需求: 需求 每天 xx 的时间: 0 11 20 * * ? 上面是…...
民安智库(第三方市民健康素养调研)居民健康素养调查的重要性及实施步骤
一、背景和意义 健康素养是衡量一个社区或国家居民对健康知识的理解,以及他们如何将这些知识应用于日常生活中的能力的重要指标。它不仅包括了基本的医学知识,如疾病预防和治疗,也包括了生活方式的改善,如合理饮食和适当运动。因…...
Linux | vim的入门手册
目录 前言 一、什么是vim 二、vim编辑器的模式 1、插入模式 (1)用vim打开文件 (2)进入插入模式 2、默认模式 (1)光标移动 (2)复制、粘贴与剪切操作 (3&#x…...
B053 项目部署
目录 Linux简介虚拟机软件安装安装centos步骤备份系统网络设置 远程访问Linux步骤永久关闭CentOS防火墙 linux命令linux文件系统linux常用命令目录相关命令文件相关命令 安装JDK先卸载自带的JDK安装JDK复制压缩包到linux解压配置环境变量 安装MySql清理旧文件安装mysqlMysql编码…...
视觉Slam面试题(不定时更新)
文章目录 0 引言1 单目、双目、深度相机和RGBD相机的区别2 特征点法与直接法的优缺点3 等距变换、相似变换、仿射变换、射影变换的区别4 单应矩阵、本质矩阵和基础矩阵的区别5 Slam中为什么用李群李代数6 解释Slam中的绑架问题7 ORB、SIFT和SURF特征点检测算法的区别8 什么是对…...
从入门到进阶 之 ElasticSearch 节点配置 集群篇
🌹 以上分享 ElasticSearch 安装部署,如有问题请指教写。🌹🌹 如你对技术也感兴趣,欢迎交流。🌹🌹🌹 如有需要,请👍点赞💖收藏🐱&a…...
UE4中无法保存项目问题
系列文章目录 文章目录 系列文章目录前言一、解决方法 前言 取消:停止保存所有资产并返回编辑器。 重试:尝试再次保存资产。 继续:仅跳过保存该资产。 当我点击继续时,关闭项目,然后重新打开项目,发现之前…...
解剖—顺序表相关OJ练习题
目录 一、删除有序数组中的重复项,返回出现一次元素的个数。 二、原地移除数组中所有数值等于val的元素 三、合并两个有序数组 四、旋转数组 五、数组形式的整数加法 一、删除有序数组中的重复项,返回出现一次元素的个数。 26. 删除有序数组中的重…...
NAT网关在阿里云的应用
NAT网关(Network Address Translation Gateway)是一种网络地址转换服务,提供NAT代理(SNAT和DNAT)能力。NAT是用于在本地网络中使用私有地址,在连接互联网时转而使用全局 IP 地址的技术。NAT实际上是为解决I…...
操作系统体系结构和OS
1.冯诺依曼计算机体系 关于冯诺伊曼系统,在这里我只是简单讲一讲,更加详细的内容可以看我的计算机组成系列。 常见的笔记本、台式机,不常见的服务器、工作站,大部分都遵守“冯诺依曼体系”,因此该计算机体系就是现代…...
AG-UI协议实战:构建智能体驱动的动态前端交互系统
1. AG-UI协议:智能体与前端交互的新范式 第一次听说AG-UI协议时,我正在为一个电商项目头疼——后台AI生成的商品推荐总需要手动同步到前端,代码里到处是setState和事件监听。直到发现这个协议,才明白原来智能体和前端可以像两个老…...
【无标题】vLLM:推理吞吐与尾延迟的资源真相
Chunked Prefil 大小影响哪些? 影响TPOT 和TTFT。 吞吐吗。 吞吐是怎么定义的? 以及QPS怎么定义的,以及并发树的关系? https://support.huaweicloud.com/intl/en-us/bestpractice-modelarts/modelarts_llm_infer_5906026.html Red…...
从YOLOv8到RTDETR:如何将训练后的YOLO指标无缝转换为COCO格式
1. 为什么需要YOLO到COCO格式转换 当你用YOLOv8官方代码训练RTDETR模型时,会发现评估结果默认输出的是YOLO格式指标。但学术界和工业界普遍采用COCO评估标准,这就好比在中国用人民币交易,到了欧洲就得换成欧元。我在去年帮某无人机公司做目标…...
PyTorch实战:手把手教你实现MobileFaceNet人脸识别模型(附完整代码)
PyTorch实战:从零构建MobileFaceNet人脸识别系统 人脸识别技术正在从实验室走向日常生活,而MobileFaceNet作为轻量级模型的代表,在移动端和嵌入式设备上展现出惊人的潜力。今天我们将深入探讨如何用PyTorch实现这个高效的神经网络架构&#x…...
前端 HTML 转 PDF
spdf 两个库转换成 PDF 文件并下载到本地。 简单说:它能让用户 “一键下载” 网页上的某个区域为 PDF(比如报表、数据统计页、合同预览页等),还预留了 “水印功能” 的注释代码(可按需启用)。 核心依赖说…...
第一次降AIGC率不知道从哪入手?这份保姆级操作手册帮你
第一次操作的话,照着下面的步骤来,15分钟内搞定降AIGC率、降AI工具保姆级测评2026、降AI。 工具选嘎嘎降AI(www.aigcleaner.com),达标率99.26%,有退款保障,操作也不复杂。 准备工作 需要准备的…...
Kettle数据迁移实战:从CSV到MySQL的高效导入指南
1. 为什么选择Kettle进行CSV到MySQL的数据迁移 第一次接触数据迁移任务时,我试过用Python脚本逐行读取CSV写入MySQL,结果导入10万条数据花了近20分钟。后来发现Kettle这个神器,同样的数据量只需要2分钟就能搞定,效率提升简直惊人。…...
从SolidWorks到ROS:六自由度机械臂URDF模型转换实战指南
1. 从SolidWorks到ROS的桥梁:URDF模型转换概述 当你费尽心思在SolidWorks中完成了六自由度机械臂的三维建模,看着那些精密的齿轮和连杆在软件中流畅转动时,脑海中可能已经浮现出它在ROS环境中大展身手的场景。但问题来了:如何让这…...
新手程序员必备:收藏这份Prompt指南,轻松驾驭大模型创造业务价值!
本文系统介绍了大模型Prompt的概念、撰写框架及核心原则,深入剖析了构建高质量Prompt的实操方法。从RTF、思考链到RISEN等五大框架,再到提升Prompt效果的策略,如明确指令、结构化输出、赋予模型思考时间等,帮助读者高效驾驭大模型…...
矩阵理论进阶:内积空间与正交变换的深度解析
1. 内积空间:从几何直觉到严格定义 第一次接触内积空间时,很多人会被各种抽象定义搞得晕头转向。其实我们可以从最熟悉的二维平面开始理解——当你计算两个向量的点积时,本质上是在测量它们的"相似程度"。这种几何直觉正是内积空间…...
