From 06df91c1b425cb7f4c49f681e9c14b165190b1e6 Mon Sep 17 00:00:00 2001 From: Emersonjsc Date: Sun, 6 Jul 2025 21:35:07 -0300 Subject: [PATCH] Frames Screens --- visao/componentes/dialogo_nova_adocao.py | 80 ++++++++++++++++ visao/frames/frame_adocao.py | 116 ++++++++++++++++++++++- visao/frames/frame_inicio.py | 23 +++-- visao/frames/frame_pessoa.py | 12 +-- visao/tela_principal.py | 7 +- 5 files changed, 214 insertions(+), 24 deletions(-) create mode 100644 visao/componentes/dialogo_nova_adocao.py diff --git a/visao/componentes/dialogo_nova_adocao.py b/visao/componentes/dialogo_nova_adocao.py new file mode 100644 index 0000000..d6b5718 --- /dev/null +++ b/visao/componentes/dialogo_nova_adocao.py @@ -0,0 +1,80 @@ +import tkinter as tk +from tkinter import ttk, messagebox +from datetime import datetime + +class DialogoNovaAdocao(tk.Toplevel): + def __init__(self, parent, bd): + super().__init__(parent) + self.bd = bd + self.result = None + + self.title("Registrar Nova Adoção") + self.geometry("400x450") + self.configure(bg="#1e1e1e") + self.transient(parent) + self.grab_set() + + self.pessoas = self.bd.pessoas.listar_todos() + self.pets = self.bd.pets.listar_todos() + + self._criar_widgets() + + def _criar_widgets(self): + main_frame = tk.Frame(self, bg="#1e1e1e", padx=20, pady=20) + main_frame.pack(fill="both", expand=True) + + # Adotante + tk.Label(main_frame, text="Adotante:", bg="#1e1e1e", fg="white").pack(anchor="w") + self.combo_pessoas = ttk.Combobox(main_frame, values=[p.nome for p in self.pessoas], state="readonly") + self.combo_pessoas.pack(fill="x", pady=(0, 10)) + + # Pets + tk.Label(main_frame, text="Selecione os Pets (use Ctrl ou Shift para múltiplos):", bg="#1e1e1e", fg="white").pack(anchor="w") + + pet_frame = tk.Frame(main_frame) + pet_frame.pack(fill="both", expand=True, pady=(0, 10)) + + self.listbox_pets = tk.Listbox(pet_frame, selectmode=tk.MULTIPLE, bg="#2c2c2c", fg="white", selectbackground="#1f6aa5") + for pet in self.pets: + self.listbox_pets.insert(tk.END, f"{pet.nome} ({pet.especie})") + + scrollbar = ttk.Scrollbar(pet_frame, orient="vertical", command=self.listbox_pets.yview) + self.listbox_pets.configure(yscrollcommand=scrollbar.set) + + self.listbox_pets.pack(side="left", fill="both", expand=True) + scrollbar.pack(side="right", fill="y") + + # Data + tk.Label(main_frame, text="Data da Adoção (DD-MM-AAAA):", bg="#1e1e1e", fg="white").pack(anchor="w") + self.entry_data = tk.Entry(main_frame, bg="#2c2c2c", fg="white", insertbackground="white") + self.entry_data.insert(0, datetime.now().strftime("%d-%m-%Y")) + self.entry_data.pack(fill="x", pady=(0, 20)) + + # Botões + botoes_frame = tk.Frame(main_frame, bg="#1e1e1e") + botoes_frame.pack(fill="x") + + btn_ok = tk.Button(botoes_frame, text="Registrar", command=self._on_ok, bg="#4CAF50", fg="white", relief="flat") + btn_ok.pack(side="right", padx=(10, 0)) + + btn_cancelar = tk.Button(botoes_frame, text="Cancelar", command=self.destroy, bg="#f44336", fg="white", relief="flat") + btn_cancelar.pack(side="right") + + def _on_ok(self): + idx_pessoa = self.combo_pessoas.current() + if idx_pessoa == -1: + messagebox.showerror("Erro", "Por favor, selecione um adotante.", parent=self) + return + + indices_pets = self.listbox_pets.curselection() + if not indices_pets: + messagebox.showerror("Erro", "Por favor, selecione pelo menos um pet.", parent=self) + return + + data = self.entry_data.get() + + pessoa_selecionada = self.pessoas[idx_pessoa] + pets_selecionados = [self.pets[i] for i in indices_pets] + + self.result = {"pessoa": pessoa_selecionada, "pets": pets_selecionados, "data": data} + self.destroy() \ No newline at end of file diff --git a/visao/frames/frame_adocao.py b/visao/frames/frame_adocao.py index 2115100..5caaf1c 100644 --- a/visao/frames/frame_adocao.py +++ b/visao/frames/frame_adocao.py @@ -1,12 +1,17 @@ import tkinter as tk from tkinter import ttk, messagebox +from modelo.adocao import Adocao +from modelo.item_adocao import ItemAdocao +from visao.componentes.dialogo_nova_adocao import DialogoNovaAdocao + class FrameAdocao(tk.Frame): def __init__(self, master=None, bd=None): super().__init__(master, bg="#1e1e1e") self.bd = bd self._criar_layout() + self.popular_treeview() def _criar_layout(self): # Título da seção @@ -17,4 +22,113 @@ class FrameAdocao(tk.Frame): bg="#1e1e1e", fg="white" ) - titulo_label.pack(pady=20) \ No newline at end of file + titulo_label.pack(pady=20) + + style = ttk.Style() + style.theme_use("default") + style.configure("Treeview", + background="#2c2c2c", + foreground="white", + rowheight=25, + fieldbackground="#2c2c2c", + bordercolor="#2c2c2c", + borderwidth=0) + style.map('Treeview', background=[('selected', '#1f6aa5')]) + + style.configure("Treeview.Heading", + background="#2c2c2c", + foreground="white", + font=("Arial", 12, "bold"), + relief="flat") + style.map("Treeview.Heading", + background=[('active', '#3c3c3c')]) + + tree_container = tk.Frame(self, bg="#1e1e1e") + tree_container.pack(pady=10, padx=20, fill="both", expand=True) + + # Configuração da Treeview para um modo hierárquico + self.tree = ttk.Treeview(tree_container, columns=("data",), show="tree headings") + + # Coluna #0 (a árvore) + self.tree.heading("#0", text="Detalhes da Adoção", anchor="w") + self.tree.column("#0", anchor="w", stretch=tk.YES, minwidth=250) + + # Coluna 'data' + self.tree.heading("data", text="Data da Adoção") + self.tree.column("data", width=150, anchor="center", stretch=tk.NO) + + scrollbar = ttk.Scrollbar(tree_container, orient="vertical", command=self.tree.yview) + self.tree.configure(yscrollcommand=scrollbar.set) + + self.tree.pack(side="left", fill="both", expand=True) + scrollbar.pack(side="right", fill="y") + + # Frame para os botões de ação + botoes_frame = tk.Frame(self, bg="#1e1e1e") + botoes_frame.pack(pady=10, padx=20, fill="x") + + # Botão Nova Adoção + btn_adicionar = tk.Button( + botoes_frame, + text="Nova Adoção", + command=self.nova_adocao, + bg="#4CAF50", + fg="white", + font=("Arial", 12), + relief="flat", + padx=10, + pady=5 + ) + btn_adicionar.pack(side="left", padx=5) + + def popular_treeview(self): + # Limpa a árvore + for i in self.tree.get_children(): + self.tree.delete(i) + + # Popula com os dados de adoções do banco de dados + for adocao in self.bd.adocoes.listar_todos(): + # Nó pai para a adoção + adocao_node = self.tree.insert( + "", "end", + iid=f"adocao_{adocao.id}", + text=f"Adoção ID: {adocao.id}", + open=True + ) + + # Nó filho para o adotante + self.tree.insert(adocao_node, "end", text=f"Adotante: {adocao.adotante.nome}") + + # Nó "pasta" para os pets + pets_node = self.tree.insert(adocao_node, "end", text="Pets Adotados", open=True) + + # Nós filhos para cada pet adotado + for item in adocao.itens: + self.tree.insert( + pets_node, "end", + text=f"{item.pet.nome} ({item.pet.especie})", + values=(item.data,) + ) + + def nova_adocao(self): + dialog = DialogoNovaAdocao(self, self.bd) + self.wait_window(dialog) + + if dialog.result: + pessoa = dialog.result["pessoa"] + pets = dialog.result["pets"] + data = dialog.result["data"] + + try: + proximo_id = self.bd.obter_proximo_id() + nova_adocao = Adocao(proximo_id, pessoa) + + for pet in pets: + item = ItemAdocao(pet, data) + nova_adocao.adicionar_item(item) + + self.bd.adocoes.inserir(nova_adocao) + self.popular_treeview() + messagebox.showinfo("Sucesso", "Adoção registrada com sucesso.") + except Exception as e: + messagebox.showerror("Erro", f"Ocorreu um erro ao registrar a adoção:\n{e}") \ No newline at end of file diff --git a/visao/frames/frame_inicio.py b/visao/frames/frame_inicio.py index 2446b57..4733c3f 100644 --- a/visao/frames/frame_inicio.py +++ b/visao/frames/frame_inicio.py @@ -1,17 +1,24 @@ import tkinter as tk class FrameInicio(tk.Frame): - def __init__(self, master=None): + def __init__(self, master=None, bd=None): super().__init__(master, bg="#1e1e1e") - - self.caixas_info = [ - {"titulo": "Pessoas", "quantidade": 0, "cor": "#ff9966"}, - {"titulo": "Pets", "quantidade": 0, "cor": "#66c2ff"}, - {"titulo": "Adoções", "quantidade": 0, "cor": "#99e699"}, - ] - + self.bd = bd + self._atualizar_dados() self._criar_layout() + def _atualizar_dados(self): + """Busca os totais do banco de dados e prepara os dados para exibição.""" + total_pessoas = len(self.bd.pessoas.listar_todos()) if self.bd else 0 + total_pets = len(self.bd.pets.listar_todos()) if self.bd else 0 + total_adocoes = len(self.bd.adocoes.listar_todos()) if self.bd else 0 + + self.caixas_info = [ + {"titulo": "Pessoas", "quantidade": total_pessoas, "cor": "#ff9966"}, + {"titulo": "Pets", "quantidade": total_pets, "cor": "#66c2ff"}, + {"titulo": "Adoções", "quantidade": total_adocoes, "cor": "#99e699"}, + ] + def _criar_layout(self): container = tk.Frame(self, bg="#1e1e1e") container.pack(pady=40, padx=50, fill="x") diff --git a/visao/frames/frame_pessoa.py b/visao/frames/frame_pessoa.py index 692970b..2eb9c31 100644 --- a/visao/frames/frame_pessoa.py +++ b/visao/frames/frame_pessoa.py @@ -10,7 +10,6 @@ class FramePessoas(tk.Frame): self._criar_layout() def _criar_layout(self): - # Título da seção titulo_label = tk.Label( self, text="GERENCIAR PESSOAS", @@ -20,13 +19,12 @@ class FramePessoas(tk.Frame): ) titulo_label.pack(pady=20) - # Estilo para a Treeview style = ttk.Style() style.theme_use("default") style.configure("Treeview", - background="#2c2c2c", # Cor de fundo da Treeview + background="#2c2c2c", foreground="white", - rowheight=25, # Altura da linha + rowheight=25, fieldbackground="#2c2c2c", bordercolor="#2c2c2c", borderwidth=0) @@ -40,7 +38,6 @@ class FramePessoas(tk.Frame): style.map("Treeview.Heading", background=[('active', '#3c3c3c')]) - # Frame para a Treeview e Scrollbar tree_container = tk.Frame(self, bg="#1e1e1e") tree_container.pack(pady=10, padx=20, fill="both", expand=True) @@ -60,11 +57,9 @@ class FramePessoas(tk.Frame): self.popular_treeview() - # Frame para os botões de ação botoes_frame = tk.Frame(self, bg="#1e1e1e") botoes_frame.pack(pady=10, padx=20, fill="x") - # Botão Adicionar btn_adicionar = tk.Button( botoes_frame, text="Adicionar", @@ -77,8 +72,7 @@ class FramePessoas(tk.Frame): pady=5 ) btn_adicionar.pack(side="left", padx=5) - - # Botão Apagar + btn_apagar = tk.Button( botoes_frame, text="Apagar", diff --git a/visao/tela_principal.py b/visao/tela_principal.py index 959b7f1..718f96d 100644 --- a/visao/tela_principal.py +++ b/visao/tela_principal.py @@ -17,11 +17,6 @@ class TelaPrincipal(tk.Tk): self.configure(bg="#1e1e1e") self.bd = BancoDeDados() - # if not self.bd.pessoas.listar_todos(): # Adiciona apenas se estiver vazio - # self.bd.pessoas.inserir(Pessoa(1, "Ana Silva")) - # self.bd.pessoas.inserir(Pessoa(2, "Bruno Costa")) - # self.bd.pessoas.inserir(Pessoa(3, "Carlos Dias")) - # self.bd.pessoas.inserir(Pessoa(4, "Daniel Santos")) self.header = tk.Frame(self, bg="#2c2c2c", height=80) @@ -87,7 +82,7 @@ class TelaPrincipal(tk.Tk): def mostrar_inicio(self): from visao.frames.frame_inicio import FrameInicio self.limpar_conteudo() - frame = FrameInicio(self.area_conteudo) + frame = FrameInicio(self.area_conteudo, self.bd) frame.pack(expand=True, fill="both") def mostrar_pessoas(self):