TxT2Docx/gui_matching_editor.py
2025-09-21 20:40:36 +08:00

171 lines
6.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
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('<<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)
# 填充表格数据
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