基于Python实现一个文件夹整理工具

 更新时间:2023年10月18日 09:48:15   作者:微小冷  
这篇文章主要为大家详细介绍了如何基于Python实现一个简单的文件夹整理工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

简介

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

文件夹对话框

第一步,实现源路径和目标路径的输入输出,从而需要自定义一个组件,代码如下,其及具体实现逻辑,可以参考:自定义文件选择按钮

import tkinter as tk
import tkinter.ttk as ttk
from tkinter.filedialog import (askopenfilename,
    askopenfilenames, askdirectory, asksaveasfilename)
from tkinter.colorchooser import askcolor

class DialogButton(ttk.Frame):
    def __init__(self, master, 
        height, widthL, widthR, logtype, label=None, text=None, 
        frmDct={}, btnDct={}, enyDct={}, logDct={}):
        w = widthL + widthR
        super().__init__(master, 
            height=height, width = w, **frmDct)
        self.pack(fill=tk.X)

        self.text = tk.StringVar() if not text else text
        ttk.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 = logtype
        self.logDct = logDct

    def setLabel(self, key, label=None):
        if label:
            return label
        labelDct = {
            "文件"   : "选择文件",
            "文件夹" : "选择路径",
            "多文件" : "选择多个文件",
            "保存" : "存储路径",
            "颜色"   : "选择颜色",
        }
        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.exists

from pathlib import Path

class 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 exs
    
    def 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 = None
            return
        self.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 = fDct

        self.initWidgets()
        self.fEnys = []
        self.exEnys = []

    def setDct(self, fDct):
        self.fDct = fDct
        self.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: return
        self.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:ExFolder
        exDct = {}
        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实现一个文件夹整理工具的文章就介绍到这了,更多相关python文件夹整理工具内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 对python中raw_input()和input()的用法详解

    对python中raw_input()和input()的用法详解

    下面小编就为大家分享一篇对python中raw_input()和input()的用法详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-04-04
  • UI自动化定位常用实现方法代码示例

    UI自动化定位常用实现方法代码示例

    这篇文章主要介绍了UI自动化定位常用实现方法代码示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • python给视频添加背景音乐并改变音量的具体方法

    python给视频添加背景音乐并改变音量的具体方法

    在本篇文章里小编给大家整理的是关于python给视频添加背景音乐并改变音量的具体方法,需要的朋友们可以参考下。
    2020-07-07
  • 如何利用Matlab制作一款真正的拼图小游戏

    如何利用Matlab制作一款真正的拼图小游戏

    这篇文章主要给大家介绍了关于如何利用Matlab制作一款真正的拼图小游戏的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • 对python中的argv和argc使用详解

    对python中的argv和argc使用详解

    今天小编就为大家分享一篇对python中的argv和argc使用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • Python使用RPC例子

    Python使用RPC例子

    本文主要介绍了Python使用RPC例子,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • linux环境下Django的安装配置详解

    linux环境下Django的安装配置详解

    这篇文章主要介绍了linux环境下Django的安装配置详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • Python数据集库Vaex秒开100GB加数据

    Python数据集库Vaex秒开100GB加数据

    这篇文章主要为大家介绍了Python数据集库Vaex秒开100GB加数据实现,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • python 读取txt中每行数据,并且保存到excel中的实例

    python 读取txt中每行数据,并且保存到excel中的实例

    下面小编就为大家分享一篇python 读取txt中每行数据,并且保存到excel中的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-04-04
  • 利用Fn.py库在Python中进行函数式编程

    利用Fn.py库在Python中进行函数式编程

    这篇文章主要介绍了利用Fn.py库在Python中进行函数式编程,基于Scala中的类似风格,需要的朋友可以参考下
    2015-04-04

最新评论