up
This commit is contained in:
parent
d0ee275f1d
commit
438523c0ea
17
.gitignore
vendored
17
.gitignore
vendored
@ -1,17 +0,0 @@
|
|||||||
|
|
||||||
__pycache__/
|
|
||||||
build/
|
|
||||||
dist/
|
|
||||||
*.egg-info/
|
|
||||||
*.egg
|
|
||||||
*.pyc
|
|
||||||
*.pyo
|
|
||||||
*.pyd
|
|
||||||
*.so
|
|
||||||
*.pyd
|
|
||||||
*.dll
|
|
||||||
*.dylib
|
|
||||||
*.lib
|
|
||||||
*.exp
|
|
||||||
*.ilk
|
|
||||||
*.pdb
|
|
77
dir.py
77
dir.py
@ -1,77 +0,0 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
|
||||||
import os
|
|
||||||
import chardet
|
|
||||||
|
|
||||||
log = 0 #是否打印日志
|
|
||||||
workPath = os.getcwd() #工作路径
|
|
||||||
|
|
||||||
# 读取配置文件
|
|
||||||
def read_config_file():
|
|
||||||
confList = [] #配置文件路径列表
|
|
||||||
# 遍历目录
|
|
||||||
for root, dirs, files in os.walk(workPath):
|
|
||||||
for file in files:
|
|
||||||
# 检查文件是否以.conf结尾
|
|
||||||
if file.endswith(".conf"):
|
|
||||||
if log:print(os.path.join(root, file))
|
|
||||||
confList.append(os.path.join(root, file))
|
|
||||||
return confList
|
|
||||||
|
|
||||||
# 处理目录结构
|
|
||||||
def config_dir_structure(confPath):
|
|
||||||
# 自动检测文件编码
|
|
||||||
with open(confPath, 'rb') as f:
|
|
||||||
raw_data = f.read()
|
|
||||||
result = chardet.detect(raw_data)
|
|
||||||
encoding = result['encoding']
|
|
||||||
# 读取配置文件
|
|
||||||
with open(confPath, 'r', encoding=encoding) as f:
|
|
||||||
lines = f.readlines()
|
|
||||||
if lines:
|
|
||||||
# 处理目录结构
|
|
||||||
for line in lines:
|
|
||||||
root = {}
|
|
||||||
stack = [(root, -1)] # 栈存储元组 (当前节点, 当前缩进级别)
|
|
||||||
for line in lines:
|
|
||||||
if not line.strip():
|
|
||||||
continue
|
|
||||||
# 计算当前行的缩进级别
|
|
||||||
indent_level = len(line) - len(line.lstrip())
|
|
||||||
# 获取当前目录名称
|
|
||||||
directory_name = line.strip()
|
|
||||||
# 在栈中找到合适的父节点
|
|
||||||
while stack and stack[-1][1] >= indent_level:
|
|
||||||
stack.pop()
|
|
||||||
# 父节点是栈中的最后一个元素
|
|
||||||
parent, _ = stack[-1]
|
|
||||||
# 将当前目录添加到父节点的字典中
|
|
||||||
parent[directory_name] = {}
|
|
||||||
# 将当前目录和其缩进级别推送到栈中
|
|
||||||
stack.append((parent[directory_name], indent_level))
|
|
||||||
return root
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 创建目录结构
|
|
||||||
def create_folders(base_path, structure):
|
|
||||||
for folder, substructure in structure.items():
|
|
||||||
current_path = os.path.join(base_path, folder)
|
|
||||||
os.makedirs(current_path, exist_ok=True)
|
|
||||||
if isinstance(substructure, dict):
|
|
||||||
create_folders(current_path, substructure)
|
|
||||||
|
|
||||||
# 配置选择器
|
|
||||||
def run_config_selector(confList):
|
|
||||||
# 根据配置文件列表创建input选择器
|
|
||||||
print("请选择配置文件:")
|
|
||||||
for i, conf in enumerate(confList):
|
|
||||||
print(f"{i+1}. {conf}")
|
|
||||||
temp = input("请输入选项:")
|
|
||||||
# 整数
|
|
||||||
if temp.isdigit():
|
|
||||||
choice = int(temp)
|
|
||||||
if choice in range(1, len(confList)+1):
|
|
||||||
return confList[choice-1]
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
579
main.py
579
main.py
@ -1,36 +1,565 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import dir as dir
|
import tkinter as tk
|
||||||
|
from tkinter import ttk, messagebox, simpledialog
|
||||||
|
import json
|
||||||
|
from typing import Dict, Optional
|
||||||
|
from PIL import Image
|
||||||
|
import subprocess
|
||||||
|
import shutil
|
||||||
|
|
||||||
def run():
|
class ConfigEditorGUI:
|
||||||
# 读取配置文件
|
def __init__(self, root):
|
||||||
conFigList = dir.read_config_file()
|
self.root = root
|
||||||
if not conFigList:
|
self.root.title("目录配置编辑器")
|
||||||
print('[没有找到配置文件]')
|
self.root.geometry("800x600")
|
||||||
input('请按任意键退出...')
|
|
||||||
|
# 设置基本样式
|
||||||
|
style = ttk.Style()
|
||||||
|
style.configure("Treeview", rowheight=25)
|
||||||
|
style.configure("TButton", padding=5)
|
||||||
|
|
||||||
|
# 当前编辑的配置文件名
|
||||||
|
self.current_file: Optional[str] = None
|
||||||
|
# 存储目录结构的字典
|
||||||
|
self.folder_structure: Dict = {}
|
||||||
|
|
||||||
|
# 添加图标缓存字典
|
||||||
|
self.icon_cache = {}
|
||||||
|
|
||||||
|
self._init_ui()
|
||||||
|
self._load_configs()
|
||||||
|
|
||||||
|
def _init_ui(self):
|
||||||
|
"""初始化用户界面"""
|
||||||
|
# 创建主框架
|
||||||
|
self.main_frame = ttk.Frame(self.root, padding="10")
|
||||||
|
self.main_frame.pack(fill=tk.BOTH, expand=True)
|
||||||
|
|
||||||
|
# 顶部工具栏
|
||||||
|
self._create_toolbar()
|
||||||
|
|
||||||
|
# 创建左右分栏
|
||||||
|
self.paned = ttk.PanedWindow(self.main_frame, orient=tk.HORIZONTAL)
|
||||||
|
self.paned.pack(fill=tk.BOTH, expand=True, pady=(10, 0))
|
||||||
|
|
||||||
|
# 左侧配置文件列表
|
||||||
|
self._create_config_list()
|
||||||
|
|
||||||
|
# 右侧目录树编辑器
|
||||||
|
self._create_tree_editor()
|
||||||
|
|
||||||
|
def _create_toolbar(self):
|
||||||
|
"""创建顶部工具栏"""
|
||||||
|
toolbar = ttk.Frame(self.main_frame)
|
||||||
|
toolbar.pack(fill=tk.X, pady=(0, 10))
|
||||||
|
|
||||||
|
ttk.Button(toolbar, text="新建配置", command=self._new_config).pack(side=tk.LEFT, padx=5)
|
||||||
|
ttk.Button(toolbar, text="删除配置", command=self._delete_config).pack(side=tk.LEFT, padx=5)
|
||||||
|
ttk.Button(toolbar, text="创建目录", command=self._create_folders).pack(side=tk.LEFT, padx=5)
|
||||||
|
|
||||||
|
def _create_config_list(self):
|
||||||
|
"""创建左侧配置文件列表"""
|
||||||
|
list_frame = ttk.LabelFrame(self.paned, text="配置文件", padding="5")
|
||||||
|
self.paned.add(list_frame, weight=1)
|
||||||
|
|
||||||
|
# 配置文件列表
|
||||||
|
self.config_listbox = tk.Listbox(list_frame)
|
||||||
|
self.config_listbox.pack(fill=tk.BOTH, expand=True)
|
||||||
|
self.config_listbox.bind('<<ListboxSelect>>', self._on_config_select)
|
||||||
|
|
||||||
|
def _set_folder_icon(self):
|
||||||
|
"""设置文件夹图标"""
|
||||||
|
selected = self.tree.selection()
|
||||||
|
if not selected or self.tree.item(selected[0])['text'] == '根目录':
|
||||||
|
return
|
||||||
|
|
||||||
|
# 创建图标选择对话框
|
||||||
|
icon_dialog = tk.Toplevel(self.root)
|
||||||
|
icon_dialog.title("选择图标")
|
||||||
|
icon_dialog.geometry("600x400")
|
||||||
|
icon_dialog.transient(self.root) # 设置为模态对话框
|
||||||
|
icon_dialog.grab_set() # 禁止与其他窗口交互
|
||||||
|
|
||||||
|
# 设置最小窗口大小
|
||||||
|
icon_dialog.minsize(400, 300)
|
||||||
|
|
||||||
|
# 将窗口居中显示
|
||||||
|
icon_dialog.update_idletasks() # 更新窗口大小
|
||||||
|
width = icon_dialog.winfo_width()
|
||||||
|
height = icon_dialog.winfo_height()
|
||||||
|
x = (icon_dialog.winfo_screenwidth() // 2) - (width // 2)
|
||||||
|
y = (icon_dialog.winfo_screenheight() // 2) - (height // 2)
|
||||||
|
icon_dialog.geometry(f'+{x}+{y}')
|
||||||
|
|
||||||
|
# 创建主框架
|
||||||
|
main_frame = ttk.Frame(icon_dialog, padding="10")
|
||||||
|
main_frame.pack(fill=tk.BOTH, expand=True)
|
||||||
|
|
||||||
|
# 创建标题标签
|
||||||
|
ttk.Label(
|
||||||
|
main_frame,
|
||||||
|
text="选择要应用的图标:",
|
||||||
|
font=('微软雅黑', 10)
|
||||||
|
).pack(anchor='w', pady=(0, 10))
|
||||||
|
|
||||||
|
# 创建图标显示区域
|
||||||
|
icon_frame = ttk.Frame(main_frame)
|
||||||
|
icon_frame.pack(fill=tk.BOTH, expand=True)
|
||||||
|
|
||||||
|
# 创建画和滚动条
|
||||||
|
canvas = tk.Canvas(icon_frame, bg='white')
|
||||||
|
scrollbar = ttk.Scrollbar(icon_frame, orient=tk.VERTICAL, command=canvas.yview)
|
||||||
|
|
||||||
|
# 创建用于放置图标的框架
|
||||||
|
scrollable_frame = ttk.Frame(canvas)
|
||||||
|
scrollable_frame.bind(
|
||||||
|
"<Configure>",
|
||||||
|
lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
|
||||||
|
)
|
||||||
|
|
||||||
|
# 创建画布窗口
|
||||||
|
canvas_window = canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
|
||||||
|
|
||||||
|
# 配置画布随窗口调整大小
|
||||||
|
def on_canvas_configure(event):
|
||||||
|
canvas.itemconfig(canvas_window, width=event.width)
|
||||||
|
canvas.bind('<Configure>', on_canvas_configure)
|
||||||
|
|
||||||
|
# 配置画布滚动
|
||||||
|
canvas.configure(yscrollcommand=scrollbar.set)
|
||||||
|
|
||||||
|
# 打包滚动组件
|
||||||
|
canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
|
||||||
|
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
|
||||||
|
|
||||||
|
# 创建网格框架
|
||||||
|
grid_frame = ttk.Frame(scrollable_frame)
|
||||||
|
grid_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
|
||||||
|
|
||||||
|
def on_icon_click(path):
|
||||||
|
self._apply_icon(selected[0], path)
|
||||||
|
icon_dialog.destroy()
|
||||||
|
|
||||||
|
# 添加"无图标"选项
|
||||||
|
no_icon_frame = ttk.Frame(grid_frame)
|
||||||
|
no_icon_frame.grid(row=0, column=0, padx=5, pady=5, sticky='nsew')
|
||||||
|
|
||||||
|
ttk.Button(
|
||||||
|
no_icon_frame,
|
||||||
|
text="无图标",
|
||||||
|
width=10,
|
||||||
|
command=lambda: on_icon_click(None)
|
||||||
|
).pack(pady=2)
|
||||||
|
ttk.Label(no_icon_frame, text="默认").pack()
|
||||||
|
|
||||||
|
# 加载实际图标
|
||||||
|
icon_count = 1 # 从1开始计数,因为0被"无图标"占用
|
||||||
|
for file in os.listdir('icons'):
|
||||||
|
if file.lower().endswith(('.ico', '.png')):
|
||||||
|
try:
|
||||||
|
icon_path = os.path.join('icons', file)
|
||||||
|
if file.lower().endswith('.png'):
|
||||||
|
# 创建预览图标(64x64)
|
||||||
|
preview_size = 64
|
||||||
|
original_icon = tk.PhotoImage(file=icon_path)
|
||||||
|
|
||||||
|
# 计算缩放比例
|
||||||
|
scale = min(preview_size / original_icon.height(), preview_size / original_icon.width())
|
||||||
|
scaled_w = int(original_icon.width() * scale)
|
||||||
|
scaled_h = int(original_icon.height() * scale)
|
||||||
|
|
||||||
|
if scaled_w > 0 and scaled_h > 0:
|
||||||
|
# 创建预览图标
|
||||||
|
preview_icon = original_icon.subsample(
|
||||||
|
max(1, original_icon.width() // scaled_w),
|
||||||
|
max(1, original_icon.height() // scaled_h)
|
||||||
|
)
|
||||||
|
|
||||||
|
# 创建图标按钮框架
|
||||||
|
btn_frame = ttk.Frame(grid_frame)
|
||||||
|
row = icon_count // 4 # 每行4个图标
|
||||||
|
col = icon_count % 4
|
||||||
|
btn_frame.grid(row=row, column=col, padx=10, pady=10, sticky='nsew')
|
||||||
|
|
||||||
|
# 创建图标按钮
|
||||||
|
btn = ttk.Button(
|
||||||
|
btn_frame,
|
||||||
|
image=preview_icon,
|
||||||
|
command=lambda p=icon_path: on_icon_click(p)
|
||||||
|
)
|
||||||
|
btn.image = preview_icon # 保持引用
|
||||||
|
btn.pack(pady=2)
|
||||||
|
|
||||||
|
# 显示文件名(限制长度)
|
||||||
|
name = file if len(file) <= 15 else file[:12] + '...'
|
||||||
|
ttk.Label(btn_frame, text=name).pack()
|
||||||
|
|
||||||
|
icon_count += 1
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"无法加载图标 {file}: {str(e)}")
|
||||||
|
|
||||||
|
# 配置网格列的权重
|
||||||
|
for i in range(4):
|
||||||
|
grid_frame.grid_columnconfigure(i, weight=1)
|
||||||
|
|
||||||
|
# 添加底部按钮框架
|
||||||
|
button_frame = ttk.Frame(main_frame)
|
||||||
|
button_frame.pack(fill=tk.X, pady=(10, 0))
|
||||||
|
|
||||||
|
ttk.Button(
|
||||||
|
button_frame,
|
||||||
|
text="取消",
|
||||||
|
command=icon_dialog.destroy
|
||||||
|
).pack(side=tk.RIGHT)
|
||||||
|
|
||||||
|
# 绑定ESC键关闭窗口
|
||||||
|
icon_dialog.bind('<Escape>', lambda e: icon_dialog.destroy())
|
||||||
|
|
||||||
|
def _apply_icon(self, item_id: str, icon_path: str):
|
||||||
|
"""应用选择的图标到文件夹"""
|
||||||
|
try:
|
||||||
|
if icon_path is None:
|
||||||
|
# 移除图标
|
||||||
|
self.tree.item(item_id, image='')
|
||||||
|
# 更新配置
|
||||||
|
path = self._get_item_path(item_id)
|
||||||
|
current = self.folder_structure.get('folders', {})
|
||||||
|
for p in path[1:]:
|
||||||
|
if p not in current:
|
||||||
|
current[p] = {}
|
||||||
|
current = current[p]
|
||||||
|
if not isinstance(current, dict):
|
||||||
|
current = {}
|
||||||
|
|
||||||
|
# 移除图标配置
|
||||||
|
if isinstance(current, dict) and '_icon' in current:
|
||||||
|
del current['_icon']
|
||||||
else:
|
else:
|
||||||
# 选择运行配置
|
# 原有的图标设置逻辑
|
||||||
data = dir.run_config_selector(conFigList)
|
rel_path = os.path.relpath(icon_path)
|
||||||
if not data:
|
if rel_path not in self.icon_cache:
|
||||||
os.system('cls')
|
self.icon_cache[rel_path] = tk.PhotoImage(file=icon_path)
|
||||||
print('[配置文件不存在]\n')
|
self.tree.item(item_id, image=self.icon_cache[rel_path])
|
||||||
run()
|
|
||||||
|
path = self._get_item_path(item_id)
|
||||||
|
current = self.folder_structure.get('folders', {})
|
||||||
|
for p in path[1:]:
|
||||||
|
if p not in current:
|
||||||
|
current[p] = {}
|
||||||
|
current = current[p]
|
||||||
|
if not isinstance(current, dict):
|
||||||
|
current = {}
|
||||||
|
|
||||||
|
current['_icon'] = rel_path
|
||||||
|
|
||||||
|
# 保存配置
|
||||||
|
self._auto_save()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
messagebox.showerror("错误", f"设置图标失败: {str(e)}")
|
||||||
|
print(f"错误详情: {str(e)}")
|
||||||
|
|
||||||
|
def _get_item_path(self, item_id: str) -> list:
|
||||||
|
"""获取树节点的完整路径"""
|
||||||
|
path = []
|
||||||
|
while item_id:
|
||||||
|
path.insert(0, self.tree.item(item_id)['text'])
|
||||||
|
item_id = self.tree.parent(item_id)
|
||||||
|
return path
|
||||||
|
|
||||||
|
def _create_tree_editor(self):
|
||||||
|
"""创建右侧目录树编辑器"""
|
||||||
|
editor_frame = ttk.LabelFrame(self.paned, text="目录结构", padding="5")
|
||||||
|
self.paned.add(editor_frame, weight=3)
|
||||||
|
|
||||||
|
self.tree = ttk.Treeview(editor_frame, selectmode='browse')
|
||||||
|
self.tree.pack(fill=tk.BOTH, expand=True)
|
||||||
|
|
||||||
|
# 右键菜单
|
||||||
|
self.context_menu = tk.Menu(self.root, tearoff=0)
|
||||||
|
self.context_menu.add_command(label="添加子目录", command=self._add_subfolder)
|
||||||
|
self.context_menu.add_command(label="设置图标", command=self._set_folder_icon)
|
||||||
|
self.context_menu.add_command(label="删除", command=self._delete_folder)
|
||||||
|
|
||||||
|
self.tree.bind("<Button-3>", self._show_context_menu)
|
||||||
|
|
||||||
|
def _load_configs(self):
|
||||||
|
"""加载所有配置文件"""
|
||||||
|
self.config_listbox.delete(0, tk.END)
|
||||||
|
for file in os.listdir('.'):
|
||||||
|
if file.endswith('.json'):
|
||||||
|
self.config_listbox.insert(tk.END, file)
|
||||||
|
|
||||||
|
def _on_config_select(self, event):
|
||||||
|
"""当选择配置文件时触发"""
|
||||||
|
selection = self.config_listbox.curselection()
|
||||||
|
if selection:
|
||||||
|
filename = self.config_listbox.get(selection[0])
|
||||||
|
self._load_config_file(filename)
|
||||||
|
|
||||||
|
def _load_config_file(self, filename: str):
|
||||||
|
"""加载指定的配置文件"""
|
||||||
|
try:
|
||||||
|
with open(filename, 'r', encoding='utf-8') as f:
|
||||||
|
self.folder_structure = json.load(f)
|
||||||
|
self.current_file = filename
|
||||||
|
self._update_tree()
|
||||||
|
except Exception as e:
|
||||||
|
messagebox.showerror("错误", f"无法加载配置文件: {str(e)}")
|
||||||
|
|
||||||
|
def _update_tree(self):
|
||||||
|
"""更新目录树显示"""
|
||||||
|
self.tree.delete(*self.tree.get_children())
|
||||||
|
folders = self.folder_structure.get('folders', {})
|
||||||
|
# 添加根节点
|
||||||
|
root = self.tree.insert('', 'end', text='根目录')
|
||||||
|
self._build_tree(root, folders)
|
||||||
|
|
||||||
|
def _build_tree(self, parent: str, folders: Dict):
|
||||||
|
"""递归构建目录树"""
|
||||||
|
for folder, content in folders.items():
|
||||||
|
# 检查是否有图标设置
|
||||||
|
icon = None
|
||||||
|
if isinstance(content, dict) and '_icon' in content:
|
||||||
|
icon_path = content['_icon']
|
||||||
|
try:
|
||||||
|
if icon_path not in self.icon_cache:
|
||||||
|
self.icon_cache[icon_path] = tk.PhotoImage(file=icon_path)
|
||||||
|
icon = self.icon_cache[icon_path]
|
||||||
|
except Exception as e:
|
||||||
|
print(f"无法加载图标 {icon_path}: {str(e)}")
|
||||||
|
|
||||||
|
# 根据是否有图标来决定传递的参数
|
||||||
|
if icon:
|
||||||
|
folder_id = self.tree.insert(parent, 'end', text=folder, image=icon)
|
||||||
else:
|
else:
|
||||||
# 处理目录结构
|
folder_id = self.tree.insert(parent, 'end', text=folder)
|
||||||
dirDict = dir.config_dir_structure(data)
|
|
||||||
os.system('cls')
|
if isinstance(content, dict):
|
||||||
if not dirDict:
|
# 过滤掉元数据键
|
||||||
print('[配置文件为空]\n')
|
subfolders = {k: v for k, v in content.items() if not k.startswith('_')}
|
||||||
run()
|
if subfolders:
|
||||||
|
self._build_tree(folder_id, subfolders)
|
||||||
|
|
||||||
|
def _show_context_menu(self, event):
|
||||||
|
"""显示右键菜单"""
|
||||||
|
item = self.tree.identify_row(event.y)
|
||||||
|
if item:
|
||||||
|
self.tree.selection_set(item)
|
||||||
|
self.context_menu.post(event.x_root, event.y_root)
|
||||||
|
|
||||||
|
def _add_subfolder(self):
|
||||||
|
"""添加子目录"""
|
||||||
|
selected = self.tree.selection()
|
||||||
|
if selected:
|
||||||
|
name = simpledialog.askstring("新建目录", "请输入目录名:")
|
||||||
|
if name:
|
||||||
|
# 添加新节点
|
||||||
|
new_item = self.tree.insert(selected[0], 'end', text=name)
|
||||||
|
# 展开父节点
|
||||||
|
self.tree.item(selected[0], open=True)
|
||||||
|
# 选中新节点
|
||||||
|
self.tree.selection_set(new_item)
|
||||||
|
# 确保新节点<E88A82><E782B9><EFBFBD>见
|
||||||
|
self.tree.see(new_item)
|
||||||
|
# 立即保存更改
|
||||||
|
self.folder_structure = {"folders": self._get_folder_structure('')}
|
||||||
|
self._auto_save()
|
||||||
|
|
||||||
|
def _delete_folder(self):
|
||||||
|
"""删除选中的目录"""
|
||||||
|
selected = self.tree.selection()
|
||||||
|
if selected and self.tree.item(selected[0])['text'] != '根目录':
|
||||||
|
self.tree.delete(selected[0])
|
||||||
|
# 立即保存更改
|
||||||
|
self.folder_structure = {"folders": self._get_folder_structure('')}
|
||||||
|
self._auto_save()
|
||||||
|
|
||||||
|
def _auto_save(self):
|
||||||
|
"""自动存当前配置"""
|
||||||
|
if not self.current_file:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(self.current_file, 'w', encoding='utf-8') as f:
|
||||||
|
json.dump(self.folder_structure, f, indent=4, ensure_ascii=False)
|
||||||
|
except Exception as e:
|
||||||
|
messagebox.showerror("错误", f"自动保存失败: {str(e)}")
|
||||||
|
|
||||||
|
def _new_config(self):
|
||||||
|
"""创建新配置文件"""
|
||||||
|
filename = simpledialog.askstring("新建配置", "请输入配置文件名:")
|
||||||
|
if filename:
|
||||||
|
if not filename.endswith('.json'):
|
||||||
|
filename += '.json'
|
||||||
|
self.folder_structure = {
|
||||||
|
"folders": {
|
||||||
|
"新文件夹": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.current_file = filename
|
||||||
|
self._auto_save()
|
||||||
|
self._load_configs()
|
||||||
|
self._update_tree()
|
||||||
|
|
||||||
|
def _get_folder_structure(self, node: str) -> Dict:
|
||||||
|
"""递归获取目录结构"""
|
||||||
|
structure = {}
|
||||||
|
children = self.tree.get_children(node)
|
||||||
|
for child in children:
|
||||||
|
item = self.tree.item(child)
|
||||||
|
child_text = item['text']
|
||||||
|
# 跳过根节
|
||||||
|
if child_text == '根目录':
|
||||||
|
structure = self._get_folder_structure(child)
|
||||||
else:
|
else:
|
||||||
|
# 修改结构以匹配创建函数的预期格式
|
||||||
|
subfolders = self._get_folder_structure(child)
|
||||||
|
if subfolders:
|
||||||
|
structure[child_text] = subfolders
|
||||||
|
else:
|
||||||
|
structure[child_text] = {}
|
||||||
|
return structure
|
||||||
|
|
||||||
|
def _create_folders(self):
|
||||||
|
"""创建实际的目录结构"""
|
||||||
|
if not self.current_file:
|
||||||
|
messagebox.showwarning("警告", "请先选择或创建配置文件")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
folders = self._get_folder_structure(
|
||||||
|
next(iter(self.tree.get_children(''))) # 获取根节点
|
||||||
|
)
|
||||||
|
create_folders('.', folders, self.current_file)
|
||||||
|
messagebox.showinfo("成功", "目录结构创建完成")
|
||||||
|
except Exception as e:
|
||||||
|
messagebox.showerror("错误", f"创建目录失败: {str(e)}")
|
||||||
|
|
||||||
|
def _delete_config(self):
|
||||||
|
"""删除当前选中的配置文件"""
|
||||||
|
selection = self.config_listbox.curselection()
|
||||||
|
if not selection:
|
||||||
|
messagebox.showwarning("警告", "请先选择要删除的配置文件")
|
||||||
|
return
|
||||||
|
|
||||||
|
filename = self.config_listbox.get(selection[0])
|
||||||
|
if messagebox.askyesno("确认删除", f"确定要删除配置文件 {filename} 吗?"):
|
||||||
|
try:
|
||||||
|
os.remove(filename)
|
||||||
|
self._load_configs() # 重新加载配置文件列表
|
||||||
|
|
||||||
|
# 如果删除的是当前打开的配置文件,清空树形视图
|
||||||
|
if filename == self.current_file:
|
||||||
|
self.current_file = None
|
||||||
|
self.folder_structure = {}
|
||||||
|
self.tree.delete(*self.tree.get_children())
|
||||||
|
except Exception as e:
|
||||||
|
messagebox.showerror("错误", f"删除失败: {str(e)}")
|
||||||
|
|
||||||
|
def init_icon_dir() -> None:
|
||||||
|
"""初始化图标目录"""
|
||||||
|
icon_dir = "图标"
|
||||||
|
if not os.path.exists(icon_dir):
|
||||||
|
os.makedirs(icon_dir)
|
||||||
|
|
||||||
|
def create_folders(base_path: str, folders: Dict, current_file) -> None:
|
||||||
|
"""递归创建目录结构"""
|
||||||
|
for folder_name, content in folders.items():
|
||||||
|
# 跳过以下划线开头的元数据键
|
||||||
|
if folder_name.startswith('_'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 构建完整路径
|
||||||
|
folder_path = os.path.join(base_path, folder_name)
|
||||||
|
|
||||||
# 创建目录
|
# 创建目录
|
||||||
base_path = '.'
|
try:
|
||||||
dir.create_folders(base_path, dirDict)
|
if not os.path.exists(folder_path):
|
||||||
print('[目录创建成功]\n')
|
os.makedirs(folder_path)
|
||||||
run()
|
|
||||||
|
|
||||||
#
|
# 调试输出
|
||||||
|
print(f"处理文件夹: {folder_name}")
|
||||||
|
print(f"内容类型: {type(content)}")
|
||||||
|
print(f"内容: {content}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"创建目录失败 {folder_path}: {str(e)}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 重新从选中的配置文件中读取folder_name中的_icon
|
||||||
|
with open(current_file, 'r', encoding='utf-8') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
icon_path = data['folders'][folder_name]['_icon']
|
||||||
|
icon_path = os.path.join(base_path, icon_path)
|
||||||
|
|
||||||
|
# 复制图标到folder_path并创建desktop.ini文件
|
||||||
|
try:
|
||||||
|
filename = os.path.basename(icon_path)
|
||||||
|
icon_name = os.path.splitext(filename)[0] + '.ico'
|
||||||
|
temp_icon_path = os.path.join('.\图标', icon_name)#临时图标
|
||||||
|
print(temp_icon_path)
|
||||||
|
img = Image.open(icon_path)
|
||||||
|
img.save(temp_icon_path, format='ICO')
|
||||||
|
|
||||||
|
shutil.copy(temp_icon_path, folder_path)
|
||||||
|
os.remove(temp_icon_path)
|
||||||
|
|
||||||
|
final_icon_path = os.path.join(folder_path, icon_name)
|
||||||
|
desktop_ini_path = os.path.join(folder_path, 'desktop.ini')
|
||||||
|
|
||||||
|
if os.path.exists(desktop_ini_path):
|
||||||
|
os.remove(desktop_ini_path)
|
||||||
|
|
||||||
|
with open(desktop_ini_path, 'w', encoding='ANSI') as f:
|
||||||
|
f.write(f"[.ShellClassInfo]\nIconResource=.\{icon_name},0")
|
||||||
|
|
||||||
|
# 设置desktop.ini为系统和隐藏文件
|
||||||
|
subprocess.run(['attrib', '+s', '+h', desktop_ini_path], shell=True)
|
||||||
|
# 设置icon文件为隐藏文件
|
||||||
|
subprocess.run(['attrib', '+s', '+h', final_icon_path], shell=True)
|
||||||
|
# 设置文件夹为只读
|
||||||
|
subprocess.run(['attrib', '+r', folder_path], shell=True)
|
||||||
|
|
||||||
|
# 清除图标缓存
|
||||||
|
os.system("attrib -h -s -r \"%userprofile%\AppData\Local\IconCache.db\"")
|
||||||
|
os.system("del /f \"%userprofile%\AppData\Local\IconCache.db\"")
|
||||||
|
os.system("attrib /s /d -h -s -r \"%userprofile%\AppData\Local\Microsoft\Windows\Explorer\*\"")
|
||||||
|
os.system("del /f \"%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_32.db\"")
|
||||||
|
os.system("del /f \"%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_96.db\"")
|
||||||
|
os.system("del /f \"%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_102.db\"")
|
||||||
|
os.system("del /f \"%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_256.db\"")
|
||||||
|
os.system("del /f \"%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_1024.db\"")
|
||||||
|
os.system("del /f \"%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_idx.db\"")
|
||||||
|
os.system("del /f \"%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_sr.db\"")
|
||||||
|
os.system("echo y|reg delete \"HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify\" /v IconStreams")
|
||||||
|
os.system("echo y|reg delete \"HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify\" /v PastIconsStream")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"设置图标失败: {str(e)}")
|
||||||
|
|
||||||
|
# 如果有子目录,递归创建
|
||||||
|
if isinstance(content, dict):
|
||||||
|
subfolders = {k: v for k, v in content.items() if not k.startswith('_')}
|
||||||
|
if subfolders:
|
||||||
|
create_folders(folder_path, subfolders)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
root = tk.Tk()
|
||||||
|
# 设置窗口图标
|
||||||
|
try:
|
||||||
|
root.iconbitmap("icons/app.ico")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 设置窗口主题色
|
||||||
|
root.configure(bg="#f0f0f0")
|
||||||
|
|
||||||
|
app = ConfigEditorGUI(root)
|
||||||
|
root.mainloop()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
run()
|
init_icon_dir()
|
||||||
|
main()
|
38
main.spec
38
main.spec
@ -1,38 +0,0 @@
|
|||||||
# -*- mode: python ; coding: utf-8 -*-
|
|
||||||
|
|
||||||
|
|
||||||
a = Analysis(
|
|
||||||
['main.py'],
|
|
||||||
pathex=[],
|
|
||||||
binaries=[],
|
|
||||||
datas=[],
|
|
||||||
hiddenimports=[],
|
|
||||||
hookspath=[],
|
|
||||||
hooksconfig={},
|
|
||||||
runtime_hooks=[],
|
|
||||||
excludes=[],
|
|
||||||
noarchive=False,
|
|
||||||
optimize=0,
|
|
||||||
)
|
|
||||||
pyz = PYZ(a.pure)
|
|
||||||
|
|
||||||
exe = EXE(
|
|
||||||
pyz,
|
|
||||||
a.scripts,
|
|
||||||
a.binaries,
|
|
||||||
a.datas,
|
|
||||||
[],
|
|
||||||
name='main',
|
|
||||||
debug=False,
|
|
||||||
bootloader_ignore_signals=False,
|
|
||||||
strip=False,
|
|
||||||
upx=True,
|
|
||||||
upx_exclude=[],
|
|
||||||
runtime_tmpdir=None,
|
|
||||||
console=True,
|
|
||||||
disable_windowed_traceback=False,
|
|
||||||
argv_emulation=False,
|
|
||||||
target_arch=None,
|
|
||||||
codesign_identity=None,
|
|
||||||
entitlements_file=None,
|
|
||||||
)
|
|
28
清除图标缓存.bat
28
清除图标缓存.bat
@ -1,28 +0,0 @@
|
|||||||
rem 关闭Windows外壳程序explorer
|
|
||||||
|
|
||||||
taskkill /f /im explorer.exe
|
|
||||||
|
|
||||||
rem 清理系统图标缓存数据库
|
|
||||||
|
|
||||||
attrib -h -s -r "%userprofile%\AppData\Local\IconCache.db"
|
|
||||||
|
|
||||||
del /f "%userprofile%\AppData\Local\IconCache.db"
|
|
||||||
|
|
||||||
attrib /s /d -h -s -r "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\*"
|
|
||||||
|
|
||||||
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_32.db"
|
|
||||||
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_96.db"
|
|
||||||
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_102.db"
|
|
||||||
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_256.db"
|
|
||||||
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_1024.db"
|
|
||||||
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_idx.db"
|
|
||||||
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_sr.db"
|
|
||||||
|
|
||||||
rem 清理 系统托盘记忆的图标
|
|
||||||
|
|
||||||
echo y|reg delete "HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify" /v IconStreams
|
|
||||||
echo y|reg delete "HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify" /v PastIconsStream
|
|
||||||
|
|
||||||
rem 重启Windows外壳程序explorer
|
|
||||||
|
|
||||||
start explorer
|
|
Loading…
x
Reference in New Issue
Block a user