代码拉取完成,页面将自动刷新
import os
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import threading
import time
class FileTreeAnalyzer(tk.Tk):
def __init__(self):
super().__init__()
self.title("文件树分析器")
self.geometry("800x600")
# 创建主框架
self.main_frame = ttk.Frame(self)
self.main_frame.pack(expand=True, fill='both', padx=10, pady=10)
# 创建控制区域
self.create_control_area()
# 创建状态显示区域
self.create_status_area()
# 创建预览区域
self.create_preview_area()
# 初始化变量
self.is_processing = False
self.current_folder = ""
def create_control_area(self):
# 文件夹选择
folder_frame = ttk.Frame(self.main_frame)
folder_frame.pack(fill='x', pady=5)
ttk.Label(folder_frame, text="目标文件夹:").pack(side='left')
self.folder_path = tk.StringVar()
ttk.Entry(folder_frame, textvariable=self.folder_path).pack(side='left', expand=True, fill='x', padx=5)
ttk.Button(folder_frame, text="浏览", command=self.select_folder).pack(side='left')
# 排除设置区域
exclude_label_frame = ttk.LabelFrame(self.main_frame, text="排除设置")
exclude_label_frame.pack(fill='x', pady=5)
# 排除文件后缀设置
exclude_ext_frame = ttk.Frame(exclude_label_frame)
exclude_ext_frame.pack(fill='x', pady=5, padx=5)
ttk.Label(exclude_ext_frame, text="排除文件后缀:").pack(side='left')
# 在这里自定义要排除的文件后缀
self.exclude_ext = tk.StringVar(value=".git,.pyc,.exe,.dll,.pyd,.so,.dylib,.cache,.png,.doc,.docx,.pdf,.bat,.sh,.txt,.gitignore,.json,.md,.jpg")
ttk.Entry(exclude_ext_frame, textvariable=self.exclude_ext).pack(side='left', expand=True, fill='x', padx=5)
# 排除文件夹设置
exclude_dir_frame = ttk.Frame(exclude_label_frame)
exclude_dir_frame.pack(fill='x', pady=5, padx=5)
ttk.Label(exclude_dir_frame, text="排除文件夹:").pack(side='left')
# 在这里自定义要排除的文件夹
self.exclude_dirs = tk.StringVar(value="temp,tmp,.git,.idea,__pycache__,venv,.venv,node_modules,build,dist,.vscode,migrations,tests,logs,instance")
ttk.Entry(exclude_dir_frame, textvariable=self.exclude_dirs).pack(side='left', expand=True, fill='x', padx=5)
# 操作按钮
button_frame = ttk.Frame(self.main_frame)
button_frame.pack(fill='x', pady=5)
self.analyze_button = ttk.Button(button_frame, text="开始分析", command=self.start_analysis)
self.analyze_button.pack(side='left', padx=5)
self.save_button = ttk.Button(button_frame, text="保存Markdown", command=self.save_markdown, state='disabled')
self.save_button.pack(side='left', padx=5)
def create_status_area(self):
status_frame = ttk.LabelFrame(self.main_frame, text="状态")
status_frame.pack(fill='x', pady=5)
self.progress = ttk.Progressbar(status_frame, mode='determinate')
self.progress.pack(fill='x', padx=5, pady=5)
self.status_label = ttk.Label(status_frame, text="就绪")
self.status_label.pack(pady=5)
def create_preview_area(self):
preview_frame = ttk.LabelFrame(self.main_frame, text="预览")
preview_frame.pack(expand=True, fill='both', pady=5)
self.preview_text = tk.Text(preview_frame, wrap='word')
self.preview_text.pack(expand=True, fill='both', padx=5, pady=5)
scrollbar = ttk.Scrollbar(preview_frame, command=self.preview_text.yview)
scrollbar.pack(side='right', fill='y')
self.preview_text.configure(yscrollcommand=scrollbar.set)
def select_folder(self):
folder = filedialog.askdirectory()
if folder:
self.folder_path.set(folder)
def start_analysis(self):
if not self.folder_path.get():
messagebox.showerror("错误", "请选择目标文件夹")
return
if self.is_processing:
return
self.is_processing = True
self.analyze_button.config(state='disabled')
self.save_button.config(state='disabled')
self.preview_text.delete(1.0, tk.END)
self.progress['value'] = 0
threading.Thread(target=self.analyze_folder, daemon=True).start()
def analyze_folder(self):
try:
self.markdown_content = "# 文件树分析报告\n\n"
self.markdown_content += f"## 目标文件夹: {self.folder_path.get()}\n\n"
# 解析排除设置
exclude_extensions = set(ext.strip() for ext in self.exclude_ext.get().split(','))
exclude_directories = set(dir.strip() for dir in self.exclude_dirs.get().split(','))
# 获取文件总数用于进度计算
total_files = 0
for root, dirs, files in os.walk(self.folder_path.get()):
# 过滤掉要排除的目录
dirs[:] = [d for d in dirs if d not in exclude_directories]
total_files += len(files)
processed_files = 0
# 生成文件树
self.markdown_content += "## 文件树结构\n\n```\n"
for root, dirs, files in os.walk(self.folder_path.get()):
# 过滤掉要排除的目录
dirs[:] = [d for d in dirs if d not in exclude_directories]
level = root.replace(self.folder_path.get(), '').count(os.sep)
indent = ' ' * level
base_dir = os.path.basename(root)
# 只显示非排除的目录
if base_dir not in exclude_directories:
self.markdown_content += f"{indent}└─ {base_dir}/\n"
# 显示非排除的文件
for file in sorted(files):
if not any(file.endswith(ext) for ext in exclude_extensions):
self.markdown_content += f"{indent} └─ {file}\n"
processed_files += 1
progress = (processed_files / total_files) * 100
self.update_progress(progress, f"处理中... {processed_files}/{total_files}")
self.markdown_content += "```\n\n"
# 生成文件内容
self.markdown_content += "## 文件内容\n\n"
processed_files = 0
for root, dirs, files in os.walk(self.folder_path.get()):
# 过滤掉要排除的目录
dirs[:] = [d for d in dirs if d not in exclude_directories]
if os.path.basename(root) in exclude_directories:
continue
for file in sorted(files):
if not any(file.endswith(ext) for ext in exclude_extensions):
file_path = os.path.join(root, file)
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
self.markdown_content += f"### {os.path.relpath(file_path, self.folder_path.get())}\n\n"
self.markdown_content += f"```\n{content}\n```\n\n"
except Exception as e:
self.markdown_content += f"### {os.path.relpath(file_path, self.folder_path.get())}\n\n"
self.markdown_content += f"无法读取文件内容: {str(e)}\n\n"
processed_files += 1
progress = (processed_files / total_files) * 100
self.update_progress(progress, f"处理中... {processed_files}/{total_files}")
self.update_preview()
self.update_progress(100, "分析完成")
except Exception as e:
self.update_status(f"错误: {str(e)}")
finally:
self.is_processing = False
self.enable_buttons()
def update_progress(self, value, status):
self.progress['value'] = value
self.update_status(status)
def update_status(self, status):
self.status_label.config(text=status)
def update_preview(self):
self.preview_text.delete(1.0, tk.END)
self.preview_text.insert(1.0, self.markdown_content)
def enable_buttons(self):
self.analyze_button.config(state='normal')
self.save_button.config(state='normal')
def save_markdown(self):
file_path = filedialog.asksaveasfilename(
defaultextension=".md",
filetypes=[("Markdown files", "*.md"), ("All files", "*.*")]
)
if file_path:
try:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(self.markdown_content)
messagebox.showinfo("成功", "Markdown文件保存成功")
except Exception as e:
messagebox.showerror("错误", f"保存文件时发生错误: {str(e)}")
if __name__ == "__main__":
app = FileTreeAnalyzer()
app.mainloop()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。