Skip to content

Instantly share code, notes, and snippets.

@krisstibex
Created June 1, 2025 06:37
Show Gist options
  • Select an option

  • Save krisstibex/e44aaa9451c2089cd75d2d078b695862 to your computer and use it in GitHub Desktop.

Select an option

Save krisstibex/e44aaa9451c2089cd75d2d078b695862 to your computer and use it in GitHub Desktop.
import os
import threading
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from tkinterdnd2 import TkinterDnD, DND_FILES
import zipfile
import py7zr
import patoolib
import locale
from PIL import Image, ImageTk
from concurrent.futures import ThreadPoolExecutor
# 多语言支持
lang = "zh" if locale.getdefaultlocale()[0].startswith("zh") else "en"
L = {
"zh": {
"title": "压缩/解压 工具箱",
"drop_here": "将文件或压缩包拖到此处\n支持 zip / 7z / tar.gz 等",
"advanced": "高级设置",
"format": "压缩格式:",
"level": "压缩率:",
"output_name": "输出文件名:",
"output_dir": "输出目录:",
"password": "密码(可选):",
"save": "保存",
"success": "成功",
"fail": "失败",
"status": "当前状态:",
"log": "日志:"
},
"en": {
"title": "Compression/Extraction Toolbox",
"drop_here": "Drop files or archives here\nSupports zip / 7z / tar.gz etc.",
"advanced": "Advanced Settings",
"format": "Format:",
"level": "Compression Level:",
"output_name": "Output Name:",
"output_dir": "Output Dir:",
"password": "Password (optional):",
"save": "Save",
"success": "Success",
"fail": "Failed",
"status": "Status:",
"log": "Logs:"
}
}[lang]
# 默认配置
config = {
"compression_format": "zip",
"compression_level": "normal",
"output_name": "archive",
"output_dir": "",
"password": ""
}
executor = ThreadPoolExecutor(max_workers=4)
# 主界面
root = TkinterDnD.Tk()
root.title(L["title"])
root.geometry("500x450")
root.resizable(False, False)
# 图标(可选)
try:
icon_img = Image.open("icon.png").resize((64, 64))
icon = ImageTk.PhotoImage(icon_img)
tk.Label(root, image=icon).pack(pady=5)
except:
pass
label = tk.Label(root, text=L["drop_here"], width=60, height=10,
relief="groove", bg="#eef", font=("Arial", 12))
label.pack(pady=10)
label.drop_target_register(DND_FILES)
status_var = tk.StringVar(value=L["status"])
log_text = tk.Text(root, height=5, state="disabled")
progress = ttk.Progressbar(root, length=400, mode="indeterminate")
progress.pack(pady=5)
tk.Label(root, textvariable=status_var).pack()
log_text.pack(padx=10, pady=5)
tk.Button(root, text=L["advanced"], command=lambda: open_config()).pack()
def log(msg):
log_text.configure(state="normal")
log_text.insert("end", msg + "\n")
log_text.configure(state="disabled")
log_text.see("end")
def update_status(msg):
status_var.set(f"{L['status']} {msg}")
def is_archive(f):
return f.lower().endswith((".zip", ".7z", ".tar.gz", ".tar", ".tgz", ".rar"))
def handle_drop(event):
files = root.tk.splitlist(event.data)
files = [f.strip() for f in files]
executor.submit(process_task, files)
def process_task(files):
update_status("Working...")
progress.start()
try:
if all(is_archive(f) for f in files):
for f in files:
extract_archive(f)
else:
compress_files(files)
except Exception as e:
log(f"{L['fail']} ❌:{str(e)}")
finally:
progress.stop()
update_status("Idle")
def extract_archive(path):
outdir = os.path.dirname(path)
pwd = config.get("password") or None
log(f"解压:{path}")
try:
if path.endswith(".zip"):
with zipfile.ZipFile(path, 'r') as z:
if pwd:
z.setpassword(pwd.encode())
z.extractall(outdir)
elif path.endswith(".7z"):
with py7zr.SevenZipFile(path, 'r', password=pwd) as z:
z.extractall(outdir)
else:
patoolib.extract_archive(path, outdir=outdir)
log(f"{L['success']} ✅:{path}")
except Exception as e:
log(f"{L['fail']} ❌:{str(e)}")
def compress_files(file_list):
outdir = config["output_dir"] or os.path.dirname(file_list[0])
outname = config["output_name"]
outpath = os.path.join(outdir, f"{outname}.{config['compression_format']}")
pwd = config.get("password") or None
log(f"压缩到:{outpath}")
try:
if config["compression_format"] == "zip":
with zipfile.ZipFile(outpath, 'w', zipfile.ZIP_DEFLATED) as z:
for f in file_list:
z.write(f, os.path.basename(f))
elif config["compression_format"] == "7z":
with py7zr.SevenZipFile(outpath, 'w', password=pwd) as z:
for f in file_list:
z.write(f, os.path.basename(f))
log(f"{L['success']} ✅:{outpath}")
except Exception as e:
log(f"{L['fail']} ❌:{str(e)}")
def open_config():
win = tk.Toplevel(root)
win.title(L["advanced"])
win.geometry("300x300")
def save():
config["compression_format"] = fmt_var.get()
config["compression_level"] = lvl_var.get()
config["output_name"] = name_var.get()
config["output_dir"] = dir_var.get()
config["password"] = pw_var.get()
win.destroy()
tk.Label(win, text=L["format"]).pack()
fmt_var = tk.StringVar(value=config["compression_format"])
tk.OptionMenu(win, fmt_var, "zip", "7z").pack()
tk.Label(win, text=L["level"]).pack()
lvl_var = tk.StringVar(value=config["compression_level"])
tk.OptionMenu(win, lvl_var, "store", "normal", "ultra").pack()
tk.Label(win, text=L["output_name"]).pack()
name_var = tk.Entry(win)
name_var.insert(0, config["output_name"])
name_var.pack()
tk.Label(win, text=L["output_dir"]).pack()
dir_var = tk.Entry(win)
dir_var.insert(0, config["output_dir"])
dir_var.pack()
tk.Label(win, text=L["password"]).pack()
pw_var = tk.Entry(win, show="*")
pw_var.insert(0, config["password"])
pw_var.pack()
tk.Button(win, text=L["save"], command=save).pack(pady=10)
label.dnd_bind('<<Drop>>', handle_drop)
root.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment