crush.py
import tkinter as tk
from tkinter import ttk
import os
import windnd
from threading import Thread
import shutil
root = tk.Tk()
root.title("文件粉碎機")
root.geometry("612x288")
root.resizable(False, False)
root.iconbitmap("icon.ico")
# 自定義字體
font_style = "Courier New"
# 創建並佈局label_warning、label_volume、text、btn_execute等組件
label_warning = tk.Label(root, text="注意:請在粉碎文件之前關閉相關的文件或程序,否則可能會出現錯誤。", foreground="red", font=(font_style, 12, "bold"))
label_warning.pack()
label_volume = tk.Label(root, text="文件數量:0\t文件夾數量:0\t總數據:0\n執行成功:0\t異常文件:0", font=(font_style, 12))
label_volume.pack(pady=20)
text = tk.Text(root, width=84, height=6, font=(font_style, 12), bg="#EFEFEF")
text.pack(padx=10, pady=10)
text.insert("insert", "將要粉碎的文件拖拽到此處!")
text.configure(state="disabled")
files_A = []
folder_A = []
folder_B = []
G = []
def handle_drag(files):
global files_A, folder_A, folder_B, G
files_A = []
folder_A = []
folder_B = []
G = []
text.configure(state="normal")
text.delete("1.0", "end")
for file in files:
file = file.decode("gbk")
if os.path.isfile(file):
text.insert("insert", file.replace("\\", "/") + "\n")
files_A.append(file.replace("\\", "/"))
else:
folder_A.append(file)
for folder in folder_A:
for a in os.walk(folder.replace("\\", "/")):
folder_B = [a[0].replace("\\", "/")] + folder_B
for file in a[2]:
text.insert("insert", os.path.join(a[0], file).replace("\\", "/") + "\n")
files_A.append(os.path.join(a[0], file).replace("\\", "/"))
for folder in folder_B:
text.insert("insert", folder + "\n")
label_volume.config(text=f"文件數量:{len(files_A)}\t文件夾數量:{len(folder_B)}\t總數據:{len(files_A)+len(folder_B)}\n執行成功:0\t異常文件:0")
text.configure(state="disabled")
def delete_file(file):
global G
if os.path.isfile(file):
try:
with open(file, "w") as f:
f.write("1")
os.remove(file)
text.configure(state="normal")
text.insert("insert", "· 處理完成 >>" + file + "\n")
text.see(tk.END)
text.configure(state="disabled")
except:
try:
os.remove(file)
except:
G.append("【異常未處理】 >>" + file)
else:
G.append("【異常未處理】 >>" + file)
def delete_folder(folder):
global G
if os.path.isfile(folder) == False:
if os.path.exists(folder):
try:
shutil.rmtree(folder)
text.configure(state="normal")
text.insert("insert", "· 處理完成 >>" + folder + "\n")
text.see(tk.END)
text.configure(state="disabled")
except:
G.append("【異常未處理】 >>" + folder)
else:
G.append("【異常未處理】 >>" + folder)
else:
G.append("【異常未處理】 >>" + folder)
def execute():
def task():
global folder_B
if btn_execute["state"] == "disabled":
return
else:
text.configure(state="normal")
text.delete("1.0", "end")
text.configure(state="disabled")
btn_execute["state"] = "disabled"
for file in files_A:
delete_file(file)
for folder in folder_B:
delete_folder(folder)
for item in G:
text.configure(state="normal")
text.insert("insert", f"{item}\n")
text.see(tk.END)
text.configure(state="disabled")
label_volume.config(text=f"文件數量:{len(files_A)}\t文件夾數量:{len(folder_B)}\t總數據:{len(files_A)+len(folder_B)}\n執行成功:{len(files_A)+len(folder_B)-len(G)}\t異常文件:{len(G)}")
btn_execute["state"] = "normal"
Thread(target=task).start()
btn_execute = tk.Button(root, text="一鍵粉碎", width=20, command=execute, font=(font_style, 12), foreground="#FFFFFF", background="#0055FF")
btn_execute.pack(pady=10)
windnd.hook_dropfiles(root, func=handle_drag)
# 自定義按鈕樣式
style = ttk.Style()
style.configure("Custom.TButton", font=(font_style, 12), foreground="#FFFFFF", background="#0055FF", padding=8)
root.mainloop()
首先,導入了必要的庫,包括 tkinter、ttk、os、windnd 和 shutil。然後創建了一個根窗口對象 root,並設置了窗口的標題、大小、不可調整大小和圖標。
接下來,定義了自定義字體樣式 font_style,並創建了一些界面組件,包括 label_warning(用於顯示警告信息)、label_volume(用於顯示文件數量和執行結果)、text(用於顯示文件路徑)、btn_execute(用於執行文件粉碎操作)等。
在 handle_drag 函數中,定義了處理拖拽文件的邏輯。它首先清空 text 中的內容,然後遍歷拖拽的文件列表,將文件路徑添加到 files_A 列表中。如果拖拽的是文件夾,還會將文件夾路徑添加到 folder_A 列表中,並遍歷文件夾中的所有文件,將文件路徑添加到 files_A 列表中。最後,將文件夾路徑添加到 folder_B 列表中,並在 text 中顯示文件和文件夾的路徑。
在 delete_file 函數中,定義了刪除文件的邏輯。如果文件存在,先嘗試以寫入方式打開文件,並寫入一個字符,然後刪除文件。如果刪除失敗,將文件路徑添加到 G 列表中。
在 delete_folder 函數中,定義了刪除文件夾的邏輯。如果文件夾不存在,直接將文件夾路徑添加到 G 列表中。如果文件夾存在,嘗試遞歸刪除文件夾。如果刪除失敗,將文件夾路徑添加到 G 列表中。
在 execute 函數中,定義了執行文件粉碎操作的邏輯。首先禁用 btn_execute 按鈕,並清空 text 中的內容。然後遍歷 files_A 列表,調用 delete_file 函數刪除文件。接著遍歷 folder_B 列表,調用 delete_folder 函數刪除文件夾。最後,將 G 列表中的異常文件信息顯示在 text 中,並更新 label_volume 的文本。最後再啟用 btn_execute 按鈕。
最後,設置了拖拽文件的處理函數 handle_drag,並啟動主事件循環 root.mainloop ()。
將粉碎的文件拖進窗口,一鍵粉碎即可