溯光笔记 – 自动序号解压工具 V1.0|开发文档

温馨提示:
公众号:溯光笔记 本站仅为个人兴趣爱好而创立 并不会收费,感谢大家的支持.如有冒犯请联系我.

溯光笔记 - 自动序号解压工具 V1.0|开发文档

文档信息

  • 软件名称:溯光笔记 - 自动序号解压工具
  • 版本:V1.0
  • 开发语言:Python
  • UI 框架:CustomTkinter
  • 目标平台:Windows
  • 作者:溯光笔记

一、软件概述

1.1 需求背景

日常解压压缩包时,多次解压容易覆盖旧文件;需要工具实现文件夹自动数字递增命名,支持自定义起始编号,规避文件覆盖风险,简化批量解压流程。

1.2 核心功能简介

  1. 读取程序目录下指定名称的 ZIP 压缩包;支持文件浏览选择压缩包
  2. 支持自定义起始编号,程序自动识别已有数字文件夹
  3. 智能序号规则:检测目录最大文件夹编号,自动顺延,杜绝覆盖
  4. 所有配置持久化保存,关闭软件自动记录参数,重启自动加载
  5. 实时运行日志输出,直观查看解压状态与报错信息
  6. 统一规范浅色商务 UI,圆角白色卡片分区,视觉分层清晰

二、UI 视觉规范(统一标准,后续工具复用)

2.1 全局色彩规范

表格

元素 色值
窗口背景 #F3F5F7(浅灰色)
分组卡片背景 #FFFFFF(纯白色圆角卡片)
主色调(控件选中) #3B82F6 科技蓝
执行按钮(解压) #22C55E 绿色
标题文字 #1F2937 深灰
说明文字 #444444 中度灰
提示文字 #666666 浅灰
日志框背景 #1F2937 深色
日志文字 #EEEEEE

2.2 组件样式规范

  1. 分组容器:圆角卡片,统一内边距,模块之间预留间距
  2. 输入框:圆角样式,支持占位提示
  3. 按钮:圆角矩形;执行操作用绿色,普通按钮使用默认蓝色
  4. 字体:微软雅黑;卡片标题 13 号加粗,正文 11~12 号常规

2.3 布局结构

plaintext

主窗口
├─【卡片1】压缩包设置(文件名输入框 + 浏览按钮)
├─【卡片2】序号配置(起始编号输入框 + 功能说明)
├─【卡片3】操作区域(绿色【开始自动解压】按钮)
└─底部通栏深色日志输出框

三、功能详细设计

3.1 参数持久化模块

  1. 配置文件:程序根目录 config.json

  2. 保存参数:压缩包文件名、自定义起始编号

  3. 触发保存时机:

    • 点击解压按钮,即时保存配置
    • 关闭软件窗口,自动保存当前所有参数
  4. 启动逻辑:程序启动优先读取配置文件;文件丢失自动使用默认配置

默认配置:{"zip_filename": "source.zip", "start_num": 1}

3.2 序号智能生成逻辑

  1. 遍历程序根目录所有文件夹,筛选名称为纯数字的文件夹

  2. 提取所有数字,得到当前最大存在编号

  3. 判断规则:

    • 最大存在编号 ≥ 用户设置的起始编号 → 新编号 = 最大编号 + 1
    • 不存在数字文件夹 / 最大编号小于起始编号 → 新编号 = 用户填写起始编号
  4. 新建文件夹并执行解压,保证永远不会覆盖历史文件

3.3 输入校验规则

  1. 起始编号仅允许正整数
  2. 填写文字、负数、0 等非法内容:自动重置编号为 1,并在日志弹窗提示警告

3.4 文件处理限制

当前仅支持 *.zip 格式压缩包;后续拓展可增加 rar、7z 支持。

四、工程代码结构

plaintext

项目根目录
├─ 溯光笔记-自动序号解压工具 v1.0.py    # 主程序代码
├─ app.ico                              # 窗口图标(可选)
└─ config.json                          # 自动生成,参数配置文件

五、环境与打包说明

5.1 Python 依赖安装

bash

pip install customtkinter

5.2 PyInstaller 打包命令

bash

pyinstaller -w -F --collect-binaries customtkinter -i app.ico "溯光笔记-自动序号解压工具 v1.0.py"

参数说明:

  • -w:不弹出黑色控制台窗口
  • -F:打包为单一 exe 文件
  • --collect-binaries customtkinter:防止 UI 样式打包丢失
  • -i app.ico:指定 exe 窗口图标

六、使用操作手册

  1. 将待解压 zip 压缩包放置程序同目录;或点击【浏览选择】指定压缩包
  2. 设置自定义起始编号(例如 100,首次解压生成文件夹100
  3. 点击【开始自动解压】执行操作
  4. 在底部日志查看执行结果
  5. 关闭软件时所有设置自动保存,下次打开无需重复填写

七、后续迭代拓展清单

  • 支持 .rar/.7z 格式解压
  • 增加解压完成后自动打开目标文件夹
  • 支持批量多个压缩包循环解压
  • 增加清理空文件夹辅助功能
  • 增加序号重置按钮

八、完整源代码

python

运行

import customtkinter as ctk
import zipfile
import os
import sys
import json

# ======================== 全局UI主题配置 ========================
ctk.set_appearance_mode("light")
ctk.set_default_color_theme("blue")

# ======================== 路径工具函数 ========================
def get_resource_path():
    if getattr(sys, 'frozen', False):
        base_path = os.path.dirname(sys.executable)
    else:
        base_path = os.path.dirname(os.path.abspath(__file__))
    return base_path

# ======================== 窗口图标 ========================
def set_window_icon(root):
    try:
        base = get_resource_path()
        ico_path = os.path.join(base, "app.ico")
        if os.path.exists(ico_path):
            root.iconbitmap(ico_path)
    except Exception:
        pass

# ======================== 配置持久化(保存压缩包名 + 起始编号) ========================
CONFIG_PATH = os.path.join(get_resource_path(), "config.json")
def load_config():
    default_cfg = {"zip_filename": "source.zip", "start_num": 1}
    if os.path.exists(CONFIG_PATH):
        try:
            with open(CONFIG_PATH,"r",encoding="utf-8") as f:
                data = json.load(f)
                return data
        except Exception:
            pass
    return default_cfg

def save_config(data):
    """关闭软件/点击解压时自动保存全部参数"""
    with open(CONFIG_PATH,"w",encoding="utf-8") as f:
        json.dump(data,f,ensure_ascii=False,indent=2)

# ======================== 核心逻辑:获取最终使用的文件夹编号 ========================
def get_target_folder(parent_dir, user_start_num):
    max_exist = 0
    for item in os.listdir(parent_dir):
        full_item = os.path.join(parent_dir, item)
        if os.path.isdir(full_item) and item.isdigit():
            num = int(item)
            if num > max_exist:
                max_exist = num
    # 规则:如果已有文件夹编号大于等于起始编号,则顺延;否则使用起始编号
    if max_exist >= user_start_num:
        use_num = max_exist + 1
    else:
        use_num = user_start_num
    target_dir = os.path.join(parent_dir, str(use_num))
    return target_dir, use_num

# ======================== 解压执行函数 ========================
def extract_zip(zip_path, start_num, log_callback):
    log_callback(f"【检测压缩包】{zip_path}")
    if not os.path.exists(zip_path):
        log_callback("❌ 错误:找不到指定压缩包!")
        return
    if not zipfile.is_zipfile(zip_path):
        log_callback("❌ 错误:文件不是有效的ZIP压缩包!")
        return
    try:
        target_folder, num = get_target_folder(get_resource_path(), start_num)
        os.makedirs(target_folder)
        log_callback(f"✅ 创建文件夹:{num}")
        with zipfile.ZipFile(zip_path, "r") as zf:
            zf.extractall(target_folder)
        log_callback(f"🎉 解压完成!输出文件夹名称:{num}\n")
    except Exception as err:
        log_callback(f"❌ 解压失败:{str(err)}")

# ======================== 主程序界面 ========================
class AutoUnzipApp(ctk.CTk):
    def __init__(self):
        super().__init__()
        self.title("溯光笔记-自动序号解压工具 v1.0")
        self.geometry("920x660")
        self.minsize(820,580)
        set_window_icon(self)
        # 加载本地保存配置
        self.cfg = load_config()

        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)
        self.grid_rowconfigure(1, weight=0)

        # 主容器 窗口背景浅灰
        main_frame = ctk.CTkFrame(self, fg_color="#F3F5F7")
        main_frame.grid(row=0, column=0, padx=12, pady=12, sticky="nsew")
        main_frame.grid_columnconfigure(0, weight=1)

        # 卡片封装函数【纯白色卡片,统一圆角样式】
        def create_card(parent, title):
            card = ctk.CTkFrame(parent, fg_color="#FFFFFF")
            card.pack(fill="x", padx=6, pady=6)
            title_label = ctk.CTkLabel(card, text=title, font=("Microsoft YaHei",13,"bold"),anchor="w")
            title_label.pack(anchor="w", padx=14, pady=(12,6))
            content = ctk.CTkFrame(card, fg_color="transparent")
            content.pack(fill="x", padx=14, pady=(0,14))
            content.grid_columnconfigure(0, weight=1)
            return content

        # ========== 卡片1:压缩包设置 ==========
        card_zip = create_card(main_frame, "压缩包设置")
        ctk.CTkLabel(card_zip, text="压缩包名称(程序根目录下):").grid(row=0,column=0,sticky="w")
        self.zip_var = ctk.StringVar(value=self.cfg["zip_filename"])
        entry_zip = ctk.CTkEntry(card_zip, textvariable=self.zip_var, height=36)
        entry_zip.grid(row=1,column=0,sticky="ew",pady=(5,0))
        # 浏览按钮
        btn_browse = ctk.CTkButton(card_zip, text="浏览选择", width=100, command=self.select_zip_file)
        btn_browse.grid(row=1,column=1,padx=(10,0))

        # ========== 卡片2:编号设置【新增起始编号输入框】 ==========
        card_num = create_card(main_frame, "序号配置")
        ctk.CTkLabel(card_num, text="自定义起始编号:").grid(row=0,column=0,sticky="w")
        self.num_var = ctk.StringVar(value=str(self.cfg["start_num"]))
        entry_num = ctk.CTkEntry(card_num, textvariable=self.num_var, height=36, width=160)
        entry_num.grid(row=1,column=0,sticky="w",pady=(5,0))
        tip_text = "说明:若目录已有更大编号,程序自动顺延,防止文件覆盖"
        ctk.CTkLabel(card_num, text=tip_text, text_color="#666666").grid(row=2,column=0,sticky="w",pady=(4,0))

        # ========== 卡片3:操作区域 ==========
        card_action = create_card(main_frame, "操作区域")
        self.start_btn = ctk.CTkButton(
            card_action,
            text="▶ 开始自动解压",
            fg_color="#22C55E",
            height=40,
            command=self.on_start
        )
        self.start_btn.pack(pady=6)

        # ========== 底部日志框 ==========
        log_container = ctk.CTkFrame(self)
        log_container.grid(row=1, column=0, padx=12, pady=(0,12), sticky="ew")
        self.log_box = ctk.CTkTextbox(log_container, height=160, fg_color="#1F2937", text_color="#EEEEEE")
        self.log_box.pack(fill="x", padx=8, pady=8)
        self.log("程序就绪,请配置参数后点击【开始自动解压】")

    def log(self, msg):
        self.log_box.insert("end", msg+"\n")
        self.log_box.see("end")
        self.update_idletasks()

    def select_zip_file(self):
        from tkinter import filedialog
        path = filedialog.askopenfilename(filetypes=[("ZIP压缩包","*.zip")])
        if path:
            filename = os.path.basename(path)
            self.zip_var.set(filename)

    def on_start(self):
        # 获取参数并校验数字
        zip_name = self.zip_var.get().strip()
        try:
            start_num = int(self.num_var.get().strip())
            if start_num < 1:
                start_num = 1
                self.log("⚠️ 编号不能小于1,自动修正为 1")
        except ValueError:
            start_num = 1
            self.log("⚠️ 输入编号非法,自动重置为 1")
            self.num_var.set("1")

        # 执行保存
        self.cfg["zip_filename"] = zip_name
        self.cfg["start_num"] = start_num
        save_config(self.cfg)

        zip_full = os.path.join(get_resource_path(), zip_name)
        extract_zip(zip_full, start_num, self.log)

    def destroy(self):
        # 关闭窗口前自动保存所有参数
        try:
            start_num = int(self.num_var.get().strip())
            if start_num <1:
                start_num =1
        except:
            start_num =1
        self.cfg["zip_filename"] = self.zip_var.get()
        self.cfg["start_num"] = start_num
        save_config(self.cfg)
        super().destroy()

if __name__ == "__main__":
    app = AutoUnzipApp()
    app.mainloop()

写到最后,AI真可以帮助大家提高工作效率,一些小工具完全可以让AI写出来,功能一点都不差,最主要能够解决问题。写这个工具也是为了方便一键创建带内置内容的文件夹,很小的一个工具,可适合自己了 就是方便,因为每个文件夹里面我还进行了分类,以前你需要手动去解压,改编号 。现在直接创建,没事就多创建几个,整理资源的时候不就方便了。

download
来源:默认下载 | 提取码:溯光笔记整理
THE END