用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.冯诺依曼计算机体系 关于冯诺伊曼系统,在这里我只是简单讲一讲,更加详细的内容可以看我的计算机组成系列。 常见的笔记本、台式机,不常见的服务器、工作站,大部分都遵守“冯诺依曼体系”,因此该计算机体系就是现代…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
