From 2af661e99061becedfb5ae207fcf9f14191ebe95 Mon Sep 17 00:00:00 2001 From: Luis Rodrigues Date: Fri, 2 May 2025 21:07:00 +0100 Subject: [PATCH] =?UTF-8?q?modulo=20de=20interface=20gr=C3=A1fico?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/gui.py | 131 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 modules/gui.py diff --git a/modules/gui.py b/modules/gui.py new file mode 100644 index 0000000..8899629 --- /dev/null +++ b/modules/gui.py @@ -0,0 +1,131 @@ +# gui.py +# Interface gráfica da aplicação UNIQ usando tkinter + +import tkinter as tk +from tkinter import filedialog, messagebox +from tkinter.ttk import Progressbar +from pathlib import Path +import threading + +from modules.logger import logger +from modules.copier import copiar_ficheiros_para_destino +from modules.scanner import listar_ficheiros, listar_ficheiros_unicos + + +class UniqGUI: + def __init__(self, master): + self.master = master + self.master.title("Uniq - Cópia de Ficheiros") + self.master.geometry("600x300") + + self.origem = tk.StringVar() + self.destino = tk.StringVar() + self.categorizar_data = tk.BooleanVar() + self.usar_criacao = tk.BooleanVar() + self.remover_duplicados = tk.BooleanVar() + + self._construir_interface() + + def _construir_interface(self): + # Selecção de origem + tk.Label(self.master, text="Pasta de Origem:").grid( + row=0, column=0, sticky="e") + tk.Entry(self.master, textvariable=self.origem, + width=40).grid(row=0, column=1) + tk.Button(self.master, text="Procurar", command=self._selecionar_origem).grid( + row=0, column=2 + ) + + # Selecção de destino + tk.Label(self.master, text="Pasta de Destino:").grid( + row=1, column=0, sticky="e" + ) + tk.Entry(self.master, textvariable=self.destino, + width=40).grid(row=1, column=1) + tk.Button(self.master, text="Procurar", command=self._selecionar_destino).grid( + row=1, column=2 + ) + + # Opções + tk.Checkbutton( + self.master, text="Categorizar por data", variable=self.categorizar_data + ).grid(row=2, column=1, sticky="w") + tk.Checkbutton( + self.master, text="Usar data de criação", variable=self.usar_criacao + ).grid(row=3, column=1, sticky="w") + tk.Checkbutton( + self.master, + text="Remover ficheiros duplicados", + variable=self.remover_duplicados, + ).grid(row=4, column=1, sticky="w") + + # Botão de início + tk.Button( + self.master, text="Iniciar cópia", command=self._iniciar_copia_thread + ).grid(row=5, column=1, pady=10) + + # Barra de progresso + self.progress = Progressbar(self.master, mode="determinate") + self.progress.grid(row=6, column=0, columnspan=3, + sticky="ew", padx=10, pady=10) + + def _selecionar_origem(self): + pasta = filedialog.askdirectory() + if pasta: + self.origem.set(pasta) + + def _selecionar_destino(self): + pasta = filedialog.askdirectory() + if pasta: + self.destino.set(pasta) + + def _iniciar_copia_thread(self): + thread = threading.Thread(target=self._iniciar_copia) + thread.start() + + def _iniciar_copia(self): + origem = self.origem.get() + destino = self.destino.get() + + if not origem or not destino: + messagebox.showerror("Erro", "Origem e destino são obrigatórios.") + return + + if self.remover_duplicados.get(): + ficheiros_dict = listar_ficheiros_unicos(origem) + lista_ficheiros = [ficheiro[0] + for ficheiro in ficheiros_dict.values()] + else: + lista_ficheiros = listar_ficheiros(origem) + + total = len(lista_ficheiros) + self.progress["maximum"] = total + + logger.info("lista de ficheiros com %d entradas", total) + + def callback(): + self.progress["value"] += 1 + + def progresso_callback(): + self.master.after(0, callback) + + copiar_ficheiros_para_destino( + lista_ficheiros, + destino, + categorizar_data=self.categorizar_data.get(), + usar_criacao=self.usar_criacao.get(), + progresso_callback=progresso_callback, + ) + + self.master.after( + 0, + lambda: messagebox.showinfo( + "Concluído", f"Foram copiados {total} ficheiros." + ), + ) + + +if __name__ == "__main__": + root = tk.Tk() + app = UniqGUI(root) + root.mainloop()