用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.冯诺依曼计算机体系 关于冯诺伊曼系统,在这里我只是简单讲一讲,更加详细的内容可以看我的计算机组成系列。 常见的笔记本、台式机,不常见的服务器、工作站,大部分都遵守“冯诺依曼体系”,因此该计算机体系就是现代…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
