TxT2Docx/gui_matching_editor.py

171 lines
6.2 KiB
Python
Raw Normal View History

2025-09-21 19:01:40 +08:00
"""
GUI匹配编辑器模块
提供编辑文件匹配关系的图形界面
"""
import os
2025-09-21 20:40:36 +08:00
import tkinter as tk
from tkinter import ttk, messagebox
2025-09-21 19:01:40 +08:00
def show_matching_editor(matched_pairs, images_root):
"""显示匹配编辑窗口,允许手动调整匹配关系"""
2025-09-21 20:40:36 +08:00
# 创建匹配编辑窗口
editor_window = tk.Toplevel()
editor_window.title('文件匹配编辑')
editor_window.geometry('900x600')
editor_window.transient()
editor_window.grab_set()
2025-09-21 19:01:40 +08:00
# 获取所有图片文件夹
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))
2025-09-21 20:40:36 +08:00
# 标题
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('<<TreeviewSelect>>', 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)
# 填充表格数据
2025-09-21 19:01:40 +08:00
for i, pair in enumerate(matched_pairs):
txt_name = pair['txt']['name']
2025-09-21 20:40:36 +08:00
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()
2025-09-21 19:01:40 +08:00
return matched_pairs