應黃同學《用Python寫了個小工具,再復雜的檔案夾,分分鐘幫你整理,拿來即用!》一文的邀請,誰寫個gui并給他投稿就送書,
那么我考慮大家的需要,結合實際,按照自己的思路寫下了這個小工具:

選擇目錄后,就可以進行整理了,下面是整理前后的效果:

看提示可以知道還支持回退,
點擊回退就可以回到之前的狀態并所有洗掉空檔案夾,
根據實際需求,需要被整理的檔案夾往往都是單層的,例如桌面的,所以程式并不支持去對子檔案夾去遞回處理,已經在子檔案夾中的檔案都會被認為是已經被整理過了,
使用效果:

若你想定制分類配置,只需要修改同一目錄下的config.json組態檔就行了:

點擊多載配置即可在不重啟程式的情況下生效,也可以直接通程序式本身提供的編輯框修改配置,點擊保存修改即可,
那么,這個工具到底是如何開發出來的呢?
開發流程
核心邏輯開發
首先定義分類字典:
file_dict = {
'圖片': ["jpeg", 'jpg', 'png', 'gif', 'webp', "bmp", "bpg", "svg", "heif", "psd"],
'視頻': ['rmvb', 'mp4', 'avi', 'mkv', 'flv', "wmv", "mov", "mpg", "mpeg", "3gp"],
"音頻": ['m4a', 'aac', 'ogg', 'oga', 'mp3', 'wma', "wav"],
"電子書": ['pdf', "epub", "mobi", "azw3", "chm", "txt"],
"資料與表格": ['xls', 'xlsx', "xlsm", 'csv', 'json', 'xml'],
"檔案": ['doc', 'docx', 'ppt', 'pptx', 'md', ".txt"],
"思維導圖": ["emmx", "mmap", "xmind"],
'程式腳本': ['py', 'java', 'html', 'sql', 'r', 'css', 'cpp', 'c', 'js', 'go'],
'壓縮檔案': ["tar", "gz", "rz", "7z", "dmg", "rar", "xar", "zip", "iso"],
'可執行程式': ['exe', 'bat', 'sys', 'com'],
'字體檔案': ['eot', 'otf', 'fon', 'font', 'ttf', 'ttc', 'woff', 'woff2']
}
然后定義一個函式用于獲取一個檔案屬于的型別:
def get_file_type(filename):
"傳入檔案名,讀取file_dict配置,根據后綴判斷檔案型別"
for file_type, suffixs in file_dict.items():
for suffix in suffixs:
if filename.endswith("."+suffix.lstrip(".")):
return file_type
return "未知型別"
呼叫方式:
get_file_type(r"D:\360安全瀏覽器下載\document.pdf")
'電子書'
下面使用pathlib庫保存移動資訊:
from pathlib import Path
def mkdirAndGetChange(path):
path = Path(path)
result = []
for file in path.glob("*"):
if file.is_dir():
continue
src_path = file.absolute()
dest_dir = get_file_type(file.name)
dest_path = path/dest_dir/file.name
dest_dir = dest_path.parent
if not dest_dir.exists():
dest_dir.mkdir()
result.append((src_path, dest_path))
return result
呼叫方式:
path = r"D:\360安全瀏覽器下載"
file_changes = mkdirAndGetChange(path)
print(file_changes)
[(WindowsPath('D:/360安全瀏覽器下載/9種常用的資料分析方法.pdf'),
WindowsPath('D:/360安全瀏覽器下載/電子書/9種常用的資料分析方法.pdf')),
...
(WindowsPath('D:/360安全瀏覽器下載/金融時間序列分析講義.pdf'),
WindowsPath('D:/360安全瀏覽器下載/電子書/金融時間序列分析講義.pdf'))]
然后需要改名時:
for src_path, dest_path in file_changes:
src_path.rename(dest_path)
還可以再還原回來:
for src_path, dest_path in file_changes:
dest_path.rename(src_path)
最后寫一個方法用于清空空白檔案夾:
def clear_black_dir(path):
path = Path(path)
for file in path.glob("*"):
if not file.is_dir():
continue
if not os.listdir(file):
file.rmdir()
path = r"D:\360安全瀏覽器下載"
clear_black_dir(path)
GUI開發
為了方便修改配置,將組態檔寫到單獨的檔案中,在封裝上述核心邏輯,命名為auto_organize.py
內容如下:
"""
小小明的代碼
CSDN主頁:https://blog.csdn.net/as604049322
"""
__author__ = '小小明'
__time__ = '2021/8/11'
import json
import os
from pathlib import Path
def load_config_json():
with open("config.json", encoding="u8") as f:
config_json = f.read()
return config_json
def save_config(config):
with open("config.json", "w", encoding="u8") as f:
f.write(config)
config_json = load_config_json()
file_dict = json.loads(config_json)
def get_file_type(filename):
"傳入檔案名,讀取file_dict配置,根據后綴判斷檔案型別"
for file_type, suffixs in file_dict.items():
for suffix in suffixs:
if filename.endswith("." + suffix.lstrip(".")):
return file_type
return "未知型別"
def mkdirAndGetChange(path):
path = Path(path)
result = []
for file in path.glob("*"):
if file.is_dir():
continue
src_path = file.absolute()
dest_dir = get_file_type(file.name)
dest_path = path / dest_dir / file.name
dest_dir = dest_path.parent
if not dest_dir.exists():
dest_dir.mkdir()
result.append((src_path, dest_path))
return result
def clear_black_dir(path):
path = Path(path)
num = 0
for file in path.glob("*"):
if not file.is_dir():
continue
if not os.listdir(file):
file.rmdir()
num += 1
return num
組態檔config.json的內容是:
{
"圖片": ["jpeg", "jpg", "png", "gif", "webp", "bmp", "bpg", "svg", "heif", "psd"],
"視頻": ["rmvb", "mp4", "avi", "mkv", "flv", "wmv", "mov", "mpg", "mpeg", "3gp"],
"音頻": ["m4a", "aac", "ogg", "oga", "mp3", "wma", "wav"],
"電子書": ["pdf", "epub", "mobi", "azw3", "chm", "txt"],
"資料與表格": ["xls", "xlsx", "xlsm", "csv", "json", "xml"],
"檔案": ["doc", "docx", "ppt", "pptx", "md", ".txt"],
"思維導圖": ["emmx", "mmap", "xmind"],
"程式腳本": ["py", "java", "html", "sql", "r", "css", "cpp", "c", "js", "go"],
"壓縮檔案": ["tar", "gz", "rz", "7z", "dmg", "rar", "xar", "zip", "iso"],
"可執行程式": ["exe", "bat", "sys", "com"],
"字體檔案": ["eot", "otf", "fon", "font", "ttf", "ttc", "woff", "woff2"]
}
GUI程式開發代碼:
"""
小小明的代碼
CSDN主頁:https://blog.csdn.net/as604049322
"""
__author__ = '小小明'
__time__ = '2021/8/11'
import json
import os
import sys
import PySimpleGUI as sg
import auto_organize
sg.change_look_and_feel("LightBlue")
layout = [
[sg.Text("被處理的檔案夾路徑(默認為當前路徑):")],
[sg.In(key="path"),
sg.FolderBrowse('...', target='path')],
[
sg.Button('開始整理', enable_events=True, key="auto_organize", font=('楷體', 15)),
sg.Button('回退', enable_events=True, key="back_before", pad=(20, 0), font=('楷體', 15)),
sg.Button('洗掉空檔案夾', enable_events=True, key="del_black", pad=(10, 0), font=('楷體', 15))
],
[sg.Text("改名配置:"),
sg.Button('多載配置', enable_events=True, key="reload_config"),
sg.Button('保存修改', enable_events=True, key="save_config")
],
[sg.Multiline(size=(46, 12), key="out")],
[sg.Text("@小小明:https://blog.csdn.net/as604049322"), ],
]
def resource_path(relative_path):
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
return os.path.join(base_path, relative_path)
window = sg.Window('檔案夾整理工具 by 小小明', layout, icon=resource_path("h.ico"))
window.finalize()
window["out"].update(auto_organize.config_json)
file_changes = None
while True:
event, values = window.read()
# print(event, values)
if event in (None,):
break # 相當于關閉界面
elif event == "auto_organize":
path = values['path']
if os.path.abspath(path) == os.path.abspath("."):
sg.popup("未選擇路徑或輸入的路徑為當前目錄,\n不允許選擇程式所在的路徑!", title="提示")
continue
file_changes = auto_organize.mkdirAndGetChange(path)
for src_path, dest_path in file_changes:
src_path.rename(dest_path)
sg.popup("整理完成,允許一次回退重置!", title="提示")
elif event == "back_before":
if not file_changes:
sg.popup("未執行過整理操作!", title="提示")
continue
for src_path, dest_path in file_changes:
dest_path.rename(src_path)
auto_organize.clear_black_dir(values['path'])
file_changes = None
sg.popup("回退完成并洗掉了全部的空檔案夾!", title="提示")
elif event == "del_black":
n = auto_organize.clear_black_dir(values['path'])
sg.popup(f"共洗掉了{n}個空檔案夾!", title="提示")
elif event == "reload_config":
auto_organize.config_json = auto_organize.load_config_json()
auto_organize.file_dict = json.loads(auto_organize.config_json)
window["out"].update(auto_organize.config_json)
elif event == "save_config":
auto_organize.save_config(values["out"])
exe打包
這里我使用的打包命令是:
pyinstaller -Fw --icon=h.ico auto_organize_gui.py --add-data="h.ico;/"
h.ico是程式的圖示檔案,
打包完成后,我們就可以愉快的使用我們的小工具啦,
相關問題解答
關于圖示資源打包的問題
這次在我使用PySimpleGUI開發中,與以往的主要區別是給程式主界面增加了圖示,這個使用window視窗函式的第三個引數傳入圖示路徑即可實作,示例:
sg.Window('PySimpleGUI',layout,icon='ico.ico')
但是問題來了,如何將圖示檔案打包到exe中并能夠順利被程式讀取到呢?
當然解決這個問題另一個麻煩的方法是,是將圖示的base64編碼硬寫到代碼中再程式解碼,顯然這種方案并不太好,修改圖示不方便,
如果最終將所有檔案到打包到一個exe時,運行環境就會有所變化,運行時會臨時進行解壓,解壓的目錄為:C:\Users\用戶名\AppData\Local\Temp\隨機目錄名, sys._MEIPASS 則存盤這個目錄的位置,我們可以根據sys模塊是否存在_MEIPASS屬性來判斷是直接運行,還是解壓到臨時目錄再運行,最終定義了如下方法:
def resource_path(relative_path):
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
return os.path.join(base_path, relative_path)
打包時使用了 –add-data引數,添加用 ; 分隔的兩個路徑,--add-data="h.ico;/"表示將h.ico檔案打包進去,運行時解壓到根目錄下,
如何制作ico圖示
- 使用ico生成的在線網站
- 使用本地軟體imagine另存圖片為ico
- 使用python庫PythonMagick
第一種方法任何人都可以直接用,百度一下,一大堆相關的網站,第二種方法該軟體可以通過百度Imagine 看圖軟體下載到,
可惜PythonMagick庫并不是可以直接使用pip進行安裝,
需要到https://www.lfd.uci.edu/~gohlke/pythonlibs/#pythonmagick下載對應自己的python版本,
下載后直接安裝whl檔案,例如:
pip install PythonMagick-0.9.19-cp37-cp37m-win_amd64.whl
在代碼中的呼叫示例為:
import PythonMagick
img = PythonMagick.Image("D:\h.jpg")
img.sample('128x128')
img.write('h.ico')
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/293618.html
標籤:python
