""" GUI匹配编辑器模块 提供编辑文件匹配关系的图形界面。 """ import os import tkinter as tk from tkinter import ttk, messagebox def show_matching_editor(matched_pairs, images_root): """显示匹配编辑窗口,允许手动调整匹配关系""" # 创建匹配编辑窗口 editor_window = tk.Toplevel() editor_window.title('文件匹配编辑') editor_window.geometry('900x600') editor_window.transient() editor_window.grab_set() # 获取所有图片文件夹 all_image_folders = [] if os.path.isdir(images_root): for root, dirs, _ in os.walk(images_root): for dir_name in dirs: folder_path = os.path.join(root, dir_name) rel_path = os.path.relpath(folder_path, images_root) all_image_folders.append((folder_path, rel_path)) # 标题 title_frame = ttk.Frame(editor_window) title_frame.pack(fill='x', padx=10, pady=10) ttk.Label(title_frame, text='文件匹配编辑', font=('', 14, 'bold')).pack() ttk.Label(title_frame, text='选择要修改的项目,然后从右侧选择图片文件夹').pack() # 主体区域(使用PanedWindow分割) paned = ttk.PanedWindow(editor_window, orient='horizontal') paned.pack(fill='both', expand=True, padx=10, pady=10) # 左侧表格区域 left_frame = ttk.Frame(paned) paned.add(left_frame, weight=2) # 表格标题 ttk.Label(left_frame, text='TXT文件匹配列表:', font=('', 10, 'bold')).pack(anchor='w', pady=(0, 5)) # 表格区域 table_frame = ttk.Frame(left_frame) table_frame.pack(fill='both', expand=True) # 创建Treeview表格 columns = ('index', 'txt_name', 'image_folder') tree = ttk.Treeview(table_frame, columns=columns, show='headings', height=15) tree.heading('index', text='序号') tree.heading('txt_name', text='TXT文件名') tree.heading('image_folder', text='匹配的图片文件夹') tree.column('index', width=60) tree.column('txt_name', width=200) tree.column('image_folder', width=250) # 表格滚动条 table_scrollbar = ttk.Scrollbar(table_frame, orient='vertical', command=tree.yview) tree.configure(yscrollcommand=table_scrollbar.set) tree.pack(side='left', fill='both', expand=True) table_scrollbar.pack(side='right', fill='y') # 右侧文件夹列表区域 right_frame = ttk.Frame(paned) paned.add(right_frame, weight=1) # 文件夹列表标题 ttk.Label(right_frame, text='可用的图片文件夹:', font=('', 10, 'bold')).pack(anchor='w', pady=(0, 5)) # 文件夹列表区域 folders_frame = ttk.Frame(right_frame) folders_frame.pack(fill='both', expand=True) # 创建文件夹列表 folders_listbox = tk.Listbox(folders_frame, selectmode='single') for folder_path, rel_path in all_image_folders: folders_listbox.insert('end', rel_path) # 文件夹列表滚动条 folders_scrollbar = ttk.Scrollbar(folders_frame, orient='vertical', command=folders_listbox.yview) folders_listbox.configure(yscrollcommand=folders_scrollbar.set) folders_listbox.pack(side='left', fill='both', expand=True) folders_scrollbar.pack(side='right', fill='y') # 操作按钮区域 button_frame = ttk.Frame(editor_window) button_frame.pack(fill='x', padx=10, pady=10) # 提供通过闭包访问变量的方式 selected_item_id = [None] # type: ignore def on_tree_select(event): """TreeView选中事件""" selection = tree.selection() if selection: selected_item_id[0] = selection[0] # type: ignore tree.bind('<>', on_tree_select) def set_matching(): """设置选中项的匹配""" if not selected_item_id[0]: messagebox.showwarning('警告', '请先选择一个TXT文件') return folder_selection = folders_listbox.curselection() if not folder_selection: messagebox.showwarning('警告', '请先选择一个图片文件夹') return # 获取选中的索引 item_values = tree.item(selected_item_id[0], 'values') row_index = int(item_values[0]) # 获取选中的文件夹 folder_index = folder_selection[0] folder_path, folder_rel = all_image_folders[folder_index] # 更新匹配关系 matched_pairs[row_index]['image_folder'] = { "path": folder_path, "name": os.path.basename(folder_path), "relative_path": folder_rel } # 更新表格显示 tree.item(selected_item_id[0], values=(row_index, item_values[1], folder_rel)) messagebox.showinfo('成功', f'已将 "{item_values[1]}" 匹配到 "{folder_rel}"') def clear_matching(): """清除选中项的匹配""" if not selected_item_id[0]: messagebox.showwarning('警告', '请先选择一个TXT文件') return # 获取选中的索引 item_values = tree.item(selected_item_id[0], 'values') row_index = int(item_values[0]) # 清除匹配关系 matched_pairs[row_index]['image_folder'] = None # 更新表格显示 tree.item(selected_item_id[0], values=(row_index, item_values[1], '无匹配')) messagebox.showinfo('成功', f'已清除 "{item_values[1]}" 的匹配关系') def apply_all(): """应用所有修改""" editor_window.destroy() # 按钮 ttk.Button(button_frame, text='设置选中项', command=set_matching).pack(side='left', padx=5) ttk.Button(button_frame, text='清除选中项', command=clear_matching).pack(side='left', padx=5) ttk.Button(button_frame, text='应用所有', command=apply_all).pack(side='right', padx=5) # 填充表格数据 for i, pair in enumerate(matched_pairs): txt_name = pair['txt']['name'] img_folder = pair['image_folder']['relative_path'] if pair['image_folder'] else '无匹配' tree.insert('', 'end', values=(i, txt_name, img_folder)) # 等待窗口关闭 editor_window.wait_window() return matched_pairs