1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
import os
import tkinter as tk
from tkinter import filedialog
import hashlib
import shutil
def calculate_hash(file_path):
"""计算文件的MD5哈希值"""
md5 = hashlib.md5()
with open(file_path, 'rb') as f:
while True:
data = f.read(8192)
if not data:
break
md5.update(data)
return md5.hexdigest()
def select_directory(entry_widget):
"""使用文件对话框选择目录并将目录路径填入文本框"""
directory = filedialog.askdirectory()
if directory:
entry_widget.delete(0, tk.END)
entry_widget.insert(0, directory)
def scan_directory(directory):
"""扫描目录下的所有图片文件,并记录路径、文件名和hash"""
image_files = []
for root, dirs, files in os.walk(directory):
for file in files:
if file.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.bmp')):
file_path = os.path.join(root, file)
file_hash = calculate_hash(file_path)
image_files.append((file_path, file, file_hash))
return image_files
def compare_directories():
"""比较两个目录的图片文件,并记录结果到日志文件"""
directory1 = entry1.get()
directory2 = entry2.get()
if not directory1 or not directory2:
result_label.config(text="请提供两个目录路径")
return
image_files1 = scan_directory(directory1)
image_files2 = scan_directory(directory2)
same_images = []
different_images = []
for file1 in image_files1:
for file2 in image_files2:
if file1[2] == file2[2]:
same_images.append((file1[0], file2[0]))
break
else:
different_images.append(file1[0])
with open('same_images.txt', 'w') as same_file:
for pair in same_images:
same_file.write(f"{pair[0]}\t{pair[1]}\n")
with open('different_images.txt', 'w') as different_file:
for file_path in different_images:
different_file.write(f"{file_path}\n")
same_count = len(same_images)
different_count = len(different_images)
log_path = os.path.abspath('different_images.txt')
# 更新统计结果和日志路径
stats_label.config(text=f"相同文件数: {same_count}\n不同文件数: {different_count}")
log_label.config(text=f"日志路径: {log_path}")
def copy_different_to_directory1():
"""复制不同的文件到目录1"""
directory1 = entry1.get()
directory2 = entry2.get()
if not directory1 or not directory2:
result_label.config(text="请提供两个目录路径")
return
copy_different_files(directory2, directory1)
result_label.config(text="复制不同的文件到目录1完成")
def copy_different_to_directory2():
"""复制不同的文件到目录2"""
directory1 = entry1.get()
directory2 = entry2.get()
if not directory1 or not directory2:
result_label.config(text="请提供两个目录路径")
return
copy_different_files(directory1, directory2)
result_label.config(text="复制不同的文件到目录2完成")
def copy_different_files(source_dir, dest_dir):
"""复制source_dir中的不同文件到dest_dir中,保留文件夹结构"""
for root, _, files in os.walk(source_dir):
for file in files:
source_file_path = os.path.join(root, file)
relative_path = os.path.relpath(source_file_path, source_dir)
dest_file_path = os.path.join(dest_dir, relative_path)
dest_dir_path = os.path.dirname(dest_file_path)
os.makedirs(dest_dir_path, exist_ok=True) # 创建目标文件夹
if not os.path.exists(dest_file_path):
shutil.copy2(source_file_path, dest_file_path)
# 创建GUI窗口
root = tk.Tk()
root.title("图片比较和复制工具")
# 创建GUI元素
frame1 = tk.Frame(root)
frame1.pack(fill=tk.BOTH, expand=True)
label1 = tk.Label(frame1, text="目录1:")
label1.grid(row=0, column=0, padx=10, pady=10, sticky="w")
entry1 = tk.Entry(frame1)
entry1.grid(row=0, column=1, padx=10, pady=10, sticky="ew")
entry1.insert(0, "请输入目录1的路径")
browse1_button = tk.Button(frame1, text="选择文件夹", command=lambda: select_directory(entry1))
browse1_button.grid(row=0, column=2, padx=10, pady=10, sticky="e")
# 设置entry1的最小宽度为50个字符
entry1.config(width=50)
frame2 = tk.Frame(root)
frame2.pack(fill=tk.BOTH, expand=True)
label2 = tk.Label(frame2, text="目录2:")
label2.grid(row=0, column=0, padx=10, pady=10, sticky="w")
entry2 = tk.Entry(frame2)
entry2.grid(row=0, column=1, padx=10, pady=10, sticky="ew")
entry2.insert(0, "请输入目录2的路径")
browse2_button = tk.Button(frame2, text="选择文件夹", command=lambda: select_directory(entry2))
browse2_button.grid(row=0, column=2, padx=10, pady=10, sticky="e")
frame_buttons = tk.Frame(root)
frame_buttons.pack(fill=tk.BOTH, expand=True)
compare_button = tk.Button(frame_buttons, text="比较图片", command=compare_directories)
compare_button.grid(row=0, column=0, padx=10, pady=10)
copy_to_dir1_button = tk.Button(frame_buttons, text="复制不同文件到目录1", command=copy_different_to_directory1)
copy_to_dir1_button.grid(row=0, column=1, padx=10, pady=10)
copy_to_dir2_button = tk.Button(frame_buttons, text="复制不同文件到目录2", command=copy_different_to_directory2)
copy_to_dir2_button.grid(row=0, column=2, padx=10, pady=10)
# 创建结果标签
result_label = tk.Label(root, text="")
result_label.pack()
# 创建统计结果和日志路径标签
result_frame = tk.Frame(root)
result_frame.pack(fill=tk.BOTH, expand=True)
stats_label = tk.Label(result_frame, text="", anchor="w")
stats_label.pack(fill=tk.BOTH, expand=True)
log_label = tk.Label(result_frame, text="", anchor="w")
log_label.pack(fill=tk.BOTH, expand=True)
# 设置窗口最小宽度为label1、entry1和browse1_button的宽度之和
min_width = label1.winfo_reqwidth() + entry1.winfo_reqwidth() + browse1_button.winfo_reqwidth() + 60 # 添加一些额外空间
root.update_idletasks() # 等待窗口更新,确保winfo_reqwidth()能够正确获取值
root.minsize(min_width, 300) # 设置最小宽度
# 居中显示窗口
root.geometry(
f"{min_width}x300+{root.winfo_screenwidth() // 2 - min_width // 2}+{root.winfo_screenheight() // 2 - 150}")
# 配置列权重,使entry1可以随窗口变宽
frame1.grid_columnconfigure(1, weight=1)
frame2.grid_columnconfigure(1, weight=1)
# 运行GUI主循环
root.mainloop()
|