|
|

楼主 |
发表于 2025-12-14 01:45:10
|
显示全部楼层
累的我半死。。。。
# ----------------------------------------------------------
# 配置文件管理 - 用于记忆上次使用的目录 2025/12/14日新增代码
# ----------------------------------------------------------
class ConfigManager:
"""配置文件管理器,用于记忆上次使用的目录(Windows专用)不适用跨平台喔~~"""
@staticmethod
def get_config_path():
"""获取配置文件路径(程序同目录的隐藏文件)"""
if getattr(sys, 'frozen', False):
exe_dir = os.path.dirname(sys.executable)
else:
exe_dir = os.path.dirname(os.path.abspath(__file__))
config_path = os.path.join(exe_dir, 'config.json')
return config_path
@staticmethod
def set_file_hidden(path, hidden=True):
"""设置或取消文件隐藏属性(仅Windows)"""
try:
if hidden:
# 设置为隐藏 (0x02)
attrs = 0x02
else:
# 设置为正常 (0x80) - 即取消隐藏
attrs = 0x80
ctypes.windll.kernel32.SetFileAttributesW(path, attrs)
return True
except Exception as e:
# print(f"设置属性失败: {e}")
return False
@staticmethod
def save_last_directory(directory):
"""保存上次使用的目录到配置文件"""
config_path = ConfigManager.get_config_path()
# 写入前,先强制取消隐藏属性,否则 Windows 会拒绝写入
if os.path.exists(config_path):
ConfigManager.set_file_hidden(config_path, hidden=False)
config_data = {
'last_directory': directory,
'last_directory_encoded': base64.b64encode(directory.encode('utf-8')).decode('utf-8')
}
try:
with open(config_path, 'w', encoding='utf-8') as f:
json.dump(config_data, f, ensure_ascii=False, indent=2)
# 写入完成后,再次设为隐藏
ConfigManager.set_file_hidden(config_path, hidden=True)
return True
except Exception as e:
print(f"保存配置失败: {e}")
return False
@staticmethod
def load_last_directory():
"""从配置文件加载上次使用的目录"""
config_path = ConfigManager.get_config_path()
if not os.path.exists(config_path):
return None
try:
with open(config_path, 'r', encoding='utf-8') as f:
config_data = json.load(f)
if 'last_directory_encoded' in config_data:
directory = base64.b64decode(config_data['last_directory_encoded']).decode('utf-8')
elif 'last_directory' in config_data:
directory = config_data['last_directory']
else:
return None
if os.path.exists(directory):
return directory
else:
return None
except Exception as e:
print(f"加载配置失败: {e}")
return None
def select_directory(parent, initial_dir=None):
"""选择目录函数,支持指定初始目录"""
# 如果提供了初始目录且存在,则尝试获取其父目录作为对话框的初始目录
if initial_dir and os.path.exists(initial_dir):
# 获取父目录
parent_dir = os.path.dirname(initial_dir)
# 如果父目录存在,使用父目录作为初始目录;否则使用原始目录
if parent_dir and os.path.exists(parent_dir):
initialdir = parent_dir
else:
initialdir = initial_dir
else:
initialdir = None
# 打开目录选择对话框
directory = filedialog.askdirectory(
title="选择编辑目录",
parent=parent,
initialdir=initialdir
)
if not directory:
return None, None
try:
# 检查目录中是否有图片文件
image_files = [f for f in os.listdir(directory) if f.lower().endswith(('.jpg', '.jpeg', '.png'))]
if not image_files:
messagebox.showerror("错误", "找不到图片!")
return None, None
# 创建错误目录
error_dir = os.path.join(os.path.dirname(directory), "aligned_error")
os.makedirs(error_dir, exist_ok=True)
# 保存到配置文件
ConfigManager.save_last_directory(directory)
return directory, error_dir
except Exception as e:
messagebox.showerror("错误", f"无法存取目录或读取档案:{e}")
return None, None
# 必须在方法开始时声明全局变量
global IMAGE_DIR, ERROR_DIR
#尝试加载上次使用的目录
last_directory = ConfigManager.load_last_directory()
try:
if last_directory:
# 如果找到上次使用的目录,直接使用
IMAGE_DIR = last_directory
ERROR_DIR = os.path.join(os.path.dirname(last_directory), "aligned_error")
os.makedirs(ERROR_DIR, exist_ok=True)
# 验证目录中是否有图片
self.image_files = self.get_image_files()
if not self.image_files:
# 如果目录中没有图片,则让用户重新选择
messagebox.showwarning("警告", "上次使用的目录中没有图片,请重新选择目录。")
result = select_directory(root, last_directory)
if result is None or result[0] is None:
sys.exit(1)
IMAGE_DIR, ERROR_DIR = result
else:
# 第一次使用或没有保存的目录,让用户选择
result = select_directory(root)
if result is None or result[0] is None:
sys.exit(1)
IMAGE_DIR, ERROR_DIR = result
except Exception as e:
print(f"初始化目录失败: {e}")
sys.exit(1)
self.image_files = self.get_image_files()
if not self.image_files:
messagebox.showerror("错误", "选择的目录中没有图片!")
sys.exit(1)
def change_directory(self):
"""切换目录功能"""
# 在函数最开始声明 global,否则后面无法读取旧值
global IMAGE_DIR, ERROR_DIR
# 检查是否有未保存的修改,有则自动保存
if self.has_unsaved_changes:
self.save_landmarks()
# 获取当前目录作为初始目录
# 现在读取 IMAGE_DIR 是安全的,因为上面已经声明了 global
current_dir = IMAGE_DIR if IMAGE_DIR else None
# 打开目录选择对话框
result = select_directory(self.root, current_dir)
if result is None or result[0] is None:
# 用户取消了选择
return
new_directory, new_error_dir = result
# 验证新目录是否有图片
temp_files = sorted([f for f in os.listdir(new_directory) if f.lower().endswith(('.jpg', '.jpeg', '.png'))])
if not temp_files:
messagebox.showerror("错误", "新目录中没有图片!")
return
# 更新全局变量
IMAGE_DIR = new_directory
ERROR_DIR = new_error_dir
# 同时保存到配置文件,确保下次启动能记住
ConfigManager.save_last_directory(IMAGE_DIR)
# 重新加载图片列表
self.image_files = self.get_image_files()
self.current_index = 0
# 更新UI显示
total_files = len(self.image_files)
max_index = total_files - 1 if total_files > 0 else 0
self.max_index_label.config(text=f"/ {max_index}")
# 加载第一张图片
self.load_current_image()
# 显示提示信息
self.msg_overlay = f"已切换到新目录: {os.path.basename(IMAGE_DIR)}"
self.render_image()
|
|