[Python] 纯文本查看 复制代码
import tkinter as tkfrom tkinter import filedialog, messagebox, ttk
import shutil
import os
import threading
class FileCopyTool:
def __init__(self, master):
self.master = master
master.title("文件复制工具 by.KOG丛林")
self.copy_tasks = []
self.current_task_index = 0
# 左上区域:选择文件/文件夹
left_frame = tk.Frame(master)
left_frame.grid(row=0, column=0, sticky='nsew')
source_label = tk.Label(left_frame, text="源文件/文件夹:")
source_label.pack(pady=(10, 0))
self.source_entry = tk.Entry(left_frame, width=50)
self.source_entry.pack(pady=(0, 10))
browse_files_button = tk.Button(left_frame, text=" 选择文件 ", command=self.browse_files)
browse_files_button.pack(side=tk.LEFT, padx=(0, 5), pady=(5, 10))
browse_dirs_button = tk.Button(left_frame, text=" 选择文件夹 ", command=self.browse_directories)
browse_dirs_button.pack(side=tk.LEFT, padx=(5, 0), pady=(5, 10))
# 右上区域:目标路径
right_frame = tk.Frame(master)
right_frame.grid(row=0, column=1, sticky='nsew')
destination_label = tk.Label(right_frame, text="目标目录:")
destination_label.pack(pady=(10, 0))
self.destination_entry = tk.Entry(right_frame, width=50)
self.destination_entry.pack(pady=(0, 10))
browse_destination_button = tk.Button(right_frame, text=" 浏览 ", command=self.browse_destination)
browse_destination_button.pack(pady=(5, 10))
# 下半区域:任务列表
bottom_frame = tk.Frame(master)
bottom_frame.grid(row=1, column=0, columnspan=2, sticky='nsew')
self.task_listbox = tk.Listbox(bottom_frame, selectmode=tk.MULTIPLE)
self.task_listbox.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=10, pady=10)
self.clear_list_button = tk.Button(bottom_frame, text="清空列表", command=self.clear_list)
self.clear_list_button.pack(side=tk.LEFT, pady=(0, 10))
self.progress_bar = ttk.Progressbar(bottom_frame, orient="horizontal", length=200, mode="determinate")
self.progress_bar.pack(side=tk.TOP, padx=10, pady=(0, 10), fill=tk.X)
self.add_task_button = tk.Button(bottom_frame, text=" 添加任务 ", command=self.add_task)
self.add_task_button.pack(side=tk.LEFT, pady=(0, 10))
self.execute_button = tk.Button(bottom_frame, text=" 开始执行 ", command=self.execute_tasks)
self.execute_button.pack(side=tk.RIGHT, pady=(0, 10))
# 设置网格权重,使任务列表框可扩展
master.grid_columnconfigure(0, weight=1)
master.grid_columnconfigure(1, weight=1)
master.grid_rowconfigure(1, weight=1)
def browse_files(self):
sources = filedialog.askopenfilenames(initialdir="/", title="选择文件",
filetypes=(("all files", "*.*"), ("text files", "*.txt")))
if sources:
self.source_entry.delete(0, tk.END)
self.source_entry.insert(0, ', '.join(sources))
def browse_directories(self):
dirs = filedialog.askdirectory(initialdir="/", title="选择文件夹")
if dirs:
self.source_entry.delete(0, tk.END)
self.source_entry.insert(0, dirs)
def browse_destination(self):
destination_dir = filedialog.askdirectory()
self.destination_entry.delete(0, tk.END)
self.destination_entry.insert(0, destination_dir)
def add_task(self):
sources = self.source_entry.get().split(', ')
destination = self.destination_entry.get()
if sources and destination:
for source in sources:
source = source.strip()
if os.path.exists(source):
self.copy_tasks.append((source, destination))
self.task_listbox.insert(tk.END, f"从 {source} 复制到 {destination}")
self.clear_entries()
def clear_list(self):
self.task_listbox.delete(0, tk.END)
def clear_entries(self):
self.source_entry.delete(0, tk.END)
self.destination_entry.delete(0, tk.END)
def update_progress(self, value):
self.progress_bar['value'] = value
self.master.update_idletasks()
def copy_file_with_progress(self, source, destination):
BUFFER_SIZE = 1024 * 1024 * 8 # 8 MB buffer size
total_size = os.path.getsize(source)
copied_size = 0
with open(source, 'rb') as src, open(destination, 'wb') as dst:
while True:
buf = src.read(BUFFER_SIZE) # Read 8MB at a time
if not buf:
break
dst.write(buf)
copied_size += len(buf)
progress = int((copied_size / total_size) * 100)
self.update_progress(progress)
def copy_folder_with_progress(self, source_folder, destination_folder):
for root, dirs, files in os.walk(source_folder):
relpath = os.path.relpath(root, source_folder)
dest_path = os.path.join(destination_folder, relpath)
os.makedirs(dest_path, exist_ok=True)
for file in files:
src_file = os.path.join(root, file)
dest_file = os.path.join(dest_path, file)
self.copy_file_with_progress(src_file, dest_file)
def execute_tasks(self):
self.current_task_index = 0
self.master.update_idletasks() # 更新进度条和任务状态
def run_tasks():
for index, task in enumerate(self.copy_tasks):
source, destination = task
if os.path.isfile(source):
destination_path = os.path.join(destination, os.path.basename(source))
self.copy_file_with_progress(source, destination_path)
elif os.path.isdir(source):
destination_path = os.path.join(destination, os.path.basename(source))
self.copy_folder_with_progress(source, destination_path)
self.task_listbox.itemconfig(index, {'bg': 'green'})
self.update_progress(100)
self.current_task_index += 1
self.master.update_idletasks()
messagebox.showinfo("完成", "所有任务已完成!")
# 在新线程中执行任务
thread = threading.Thread(target=run_tasks)
thread.start()
if __name__ == "__main__":
root = tk.Tk()
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)
root.grid_columnconfigure(1, weight=1)
my_gui = FileCopyTool(root)
root.mainloop()