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 ()。
将粉碎的文件拖进窗口,一件粉碎即可