Hi! Could we please enable some services and cookies to improve your experience and our website?

SQLize Online / PHPize Online  /  SQLtest Online

A A A
Share code      Blog   Popular   FAQ

Online Sandbox for SQL and PHP: Write, Run, Test, and Share SQL Queries and PHP Code

Copy Format Clear
import tkinter as tk from tkinter import tk, messagebox import mysql.connector from mysql.connector import Error # configuracao do banco DB_CONFIG = { 'host': 'localhost', 'user': 'root', 'password': '', 'database': 'loja_conserto' } # -dabse ullitarios def create_database_and_tables(): """Create the database and tables if they do not exist.""" try: conn = mysql.connector.connect( host=DB_CONFIG['host'], user=DB_CONFIG['user'], password=DB_CONFIG['password']) cursor = conn.cursor() cursor.execute(f"CREATE DATABASE IF NOT EXISTS {DB_CONFIG['database']}") conn.close() conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute(""" CREATE TABLE IF NOT EXISTS clientes ( id INT AUTO_INCREMENT PRIMARY KEY, nome VARCHAR(100) NOT NULL, telefone VARCHAR(20), email VARCHAR(100) ) """) cursor.execute(""" CREATE TABLE IF NOT EXISTS servicos ( id INT AUTO_INCREMENT PRIMARY KEY, cliente_id INT NOT NULL, descricao TEXT NOT NULL, valor DECIMAL(10,2) NOT NULL, status VARCHAR(50) NOT NULL, FOREIGN KEY (cliente_id) REFERENCES clientes(id) ON DELETE CASCADE ON UPDATE CASCADE ) """) conn.commit() cursor.close() conn.close() except Error as e: messagebox.showerror("Database Error", f"Error creating database or tables:\n{e}") # --- Cliente CRUD --- def add_cliente(nome, telefone, email): try: conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute("INSERT INTO clientes (nome, telefone, email) VALUES (%s, %s, %s)", (nome, telefone, email)) conn.commit() cursor.close() conn.close() except Error as e: messagebox.showerror("Erro Cliente", f"Erro ao adicionar cliente:\n{e}") def update_cliente(cliente_id, nome, telefone, email): try: conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute("UPDATE clientes SET nome=%s, telefone=%s, email=%s WHERE id=%s", (nome, telefone, email, cliente_id)) conn.commit() cursor.close() conn.close() except Error as e: messagebox.showerror("Erro Cliente", f"Erro ao atualizar cliente:\n{e}") def delete_cliente(cliente_id): try: conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute("DELETE FROM clientes WHERE id=%s", (cliente_id,)) conn.commit() cursor.close() conn.close() except Error as e: messagebox.showerror("Erro Cliente", f"Erro ao deletar cliente:\n{e}") def get_clientes(): clientes = [] try: conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute("SELECT id, nome, telefone, email FROM clientes ORDER BY nome") clientes = cursor.fetchall() cursor.close() conn.close() except Error as e: messagebox.showerror("Erro Cliente", f"Erro ao carregar clientes:\n{e}") return clientes # --- Servico CRUD --- def add_servico(cliente_id, descricao, valor, status): try: conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute( "INSERT INTO servicos (cliente_id, descricao, valor, status) VALUES (%s, %s, %s, %s)", (cliente_id, descricao, valor, status)) conn.commit() cursor.close() conn.close() except Error as e: messagebox.showerror("Erro Serviço", f"Erro ao adicionar serviço:\n{e}") def update_servico(servico_id, cliente_id, descricao, valor, status): try: conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute( "UPDATE servicos SET cliente_id=%s, descricao=%s, valor=%s, status=%s WHERE id=%s", (cliente_id, descricao, valor, status, servico_id)) conn.commit() cursor.close() conn.close() except Error as e: messagebox.showerror("Erro Serviço", f"Erro ao atualizar serviço:\n{e}") def delete_servico(servico_id): try: conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute("DELETE FROM servicos WHERE id=%s", (servico_id,)) conn.commit() cursor.close() conn.close() except Error as e: messagebox.showerror("Erro Serviço", f"Erro ao deletar serviço:\n{e}") def get_servicos(): servicos = [] try: conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() # juntar clientes cursor.execute(""" SELECT s.id, s.cliente_id, c.nome, s.descricao, s.valor, s.status FROM servicos s JOIN clientes c ON s.cliente_id = c.id ORDER BY s.id DESC """) servicos = cursor.fetchall() cursor.close() conn.close() except Error as e: messagebox.showerror("Erro Serviço", f"Erro ao carregar serviços:\n{e}") return servicos # --- GUI --- class LojaConsertoApp: def __init__(self, master): self.master = master master.title("Loja de Conserto de Computadores") master.geometry("900x600") master.configure(bg="#f0f0f0") style = tk.Style() style.theme_use('clam') style.configure('TNotebook.Tab', font=('Segoe UI', 12, 'bold'), padding=[10,5]) # Notebook tabs self.notebook = tk.Notebook(master) self.notebook.pack(fill='both', expand=True, padx=10, pady=10) self.frame_clientes = tk.Frame(self.notebook) self.frame_servicos = tk.Frame(self.notebook) self.notebook.add(self.frame_clientes, text="Clientes") self.notebook.add(self.frame_servicos, text="Serviços") self.create_cliente_tab() self.create_servico_tab() # ------------ Clientes Tab ------------ def create_cliente_tab(self): frame = self.frame_clientes # Form fields form_frame = tk.LabelFrame(frame, text="Cadastro / Edição de Cliente", padding=10) form_frame.pack(fill='x', padx=10, pady=10) tk.Label(form_frame, text="Nome *:").grid(row=0, column=0, sticky='w') self.cliente_nome_var = tk.StringVar() self.entry_cliente_nome = tk.Entry(form_frame, textvariable=self.cliente_nome_var, width=40) self.entry_cliente_nome.grid(row=0, column=1, sticky='w') tk.Label(form_frame, text="Telefone:").grid(row=1, column=0, sticky='w') self.cliente_telefone_var = tk.StringVar() self.entry_cliente_telefone = tk.Entry(form_frame, textvariable=self.cliente_telefone_var, width=40) self.entry_cliente_telefone.grid(row=1, column=1, sticky='w') tk.Label(form_frame, text="Email:").grid(row=2, column=0, sticky='w') self.cliente_email_var = tk.StringVar() self.entry_cliente_email = tk.Entry(form_frame, textvariable=self.cliente_email_var, width=40) self.entry_cliente_email.grid(row=2, column=1, sticky='w') # Butons btn_frame = tk.Frame(form_frame) btn_frame.grid(row=3, column=0, columnspan=2, pady=10) self.btn_add_cliente = tk.Buton(btn_frame, text="Adicionar", command=self.add_cliente) self.btn_add_cliente.grid(row=0, column=0, padx=5) self.btn_update_cliente = tk.Buton(btn_frame, text="Atualizar", command=self.update_cliente) self.btn_update_cliente.grid(row=0, column=1, padx=5) self.btn_update_cliente.state(['disabled']) self.btn_delete_cliente = tk.Buton(btn_frame, text="Excluir", command=self.delete_cliente) self.btn_delete_cliente.grid(row=0, column=2, padx=5) self.btn_delete_cliente.state(['disabled']) self.btn_clear_cliente = tk.Buton(btn_frame, text="Limpar", command=self.clear_cliente_form) self.btn_clear_cliente.grid(row=0, column=3, padx=5) # Treeview lis�ng clientes list_frame = tk.LabelFrame(frame, text="Clientes Cadastrados", padding=10) list_frame.pack(fill='both', expand=True, padx=10, pady=10) columns = ("id", "nome", "telefone", "email") self.tree_clientes = tk.Treeview(list_frame, columns=columns, show='headings', selectmode='browse') for col in columns: self.tree_clientes.heading(col, text=col.capitalize()) self.tree_clientes.column(col, anchor='center') self.tree_clientes.pack(fill='both', expand=True) self.tree_clientes.bind('<<TreeviewSelect>>', self.on_cliente_select) self.load_clientes() def load_clientes(self): for i in self.tree_clientes.get_children(): self.tree_clientes.delete(i) for cliente in get_clientes(): self.tree_clientes.insert('', 'end', values=cliente) self.clear_cliente_form() def add_cliente(self): nome = self.cliente_nome_var.get().strip() telefone = self.cliente_telefone_var.get().strip() email = self.cliente_email_var.get().strip() if not nome: messagebox.showwarning("Validação", "O campo Nome é obrigatório.") return add_cliente(nome, telefone, email) messagebox.showinfo("Sucesso", "Cliente adicionado com sucesso.") self.load_clientes() self.load_cliente_combobox() # refresh clients combo in services tab def on_cliente_select(self, event): selected = self.tree_clientes.focus() if not selected: return values = self.tree_clientes.item(selected, 'values') self.selected_cliente_id = values[0] self.cliente_nome_var.set(values[1]) self.cliente_telefone_var.set(values[2]) self.cliente_email_var.set(values[3]) self.btn_update_cliente.state(['!disabled']) self.btn_delete_cliente.state(['!disabled']) self.btn_add_cliente.state(['disabled']) def update_cliente(self): if not hasattr(self, 'selected_cliente_id'): return nome = self.cliente_nome_var.get().strip() telefone = self.cliente_telefone_var.get().strip() email = self.cliente_email_var.get().strip() if not nome: messagebox.showwarning("Validação", "O campo Nome é obrigatório.") return update_cliente(self.selected_cliente_id, nome, telefone, email) messagebox.showinfo("Sucesso", "Cliente atualizado com sucesso.") self.load_clientes() self.load_cliente_combobox() # refresh clients combo in services tab def delete_cliente(self): if not hasattr(self, 'selected_cliente_id'): return confirm = messagebox.askyesno("Confirmação","Deseja realmente excluir este cliente? Isso também removerá os serviços vinculados.") if confirm: delete_cliente(self.selected_cliente_id) messagebox.showinfo("Sucesso", "Cliente excluído com sucesso.") self.load_clientes() self.load_cliente_combobox() # f5 def clear_cliente_form(self): self.cliente_nome_var.set("") self.cliente_telefone_var.set("") self.cliente_email_var.set("") self.btn_update_cliente.state(['disabled']) self.btn_delete_cliente.state(['disabled']) self.btn_add_cliente.state(['!disabled']) if hasattr(self, 'selected_cliente_id'): del self.selected_cliente_id # Also reset selecion in tree self.tree_clientes.selection_remove(self.tree_clientes.selection()) # ------------ Serviços Tab ------------ def create_servico_tab(self): frame = self.frame_servicos # Form fields form_frame = tk.LabelFrame(frame, text="Cadastro / Edição de Serviço", padding=10) form_frame.pack(fill='x', padx=10, pady=10) tk.Label(form_frame, text="Cliente *:").grid(row=0, column=0, sticky='w') self.servico_cliente_var = tk.StringVar() self.combo_servico_cliente = tk.Combobox(form_frame, textvariable=self.servico_cliente_var, state='readonly', width=38) self.combo_servico_cliente.grid(row=0, column=1, sticky='w') tk.Label(form_frame, text="Descrição *:").grid(row=1, column=0, sticky='w') self.servico_descricao_var = tk.StringVar() self.entry_servico_descricao = tk.Entry(form_frame, textvariable=self.servico_descricao_var, width=40) self.entry_servico_descricao.grid(row=1, column=1, sticky='w') tk.Label(form_frame, text="Valor (R$) *:").grid(row=2, column=0, sticky='w') self.servico_valor_var = tk.StringVar() self.entry_servico_valor = tk.Entry(form_frame, textvariable=self.servico_valor_var, width=40) self.entry_servico_valor.grid(row=2, column=1, sticky='w') tk.Label(form_frame, text="Status *:").grid(row=3, column=0, sticky='w') self.servico_status_var = tk.StringVar() self.combo_servico_status = tk.Combobox(form_frame, textvariable=self.servico_status_var, state='readonly', values=["Recebido", "Em andamento", "Concluído", "Entregue", "Cancelado"], width=37) self.combo_servico_status.grid(row=3, column=1, sticky='w') self.combo_servico_status.current(0) # Butons btn_frame = tk.Frame(form_frame) btn_frame.grid(row=4, column=0, columnspan=2, pady=10) self.btn_add_servico = tk.Buton(btn_frame, text="Adicionar", command=self.add_servico) self.btn_add_servico.grid(row=0, column=0, padx=5) self.btn_update_servico = tk.Buton(btn_frame, text="Atualizar", command=self.update_servico) self.btn_update_servico.grid(row=0, column=1, padx=5) self.btn_update_servico.state(['disabled']) self.btn_delete_servico = tk.Buton(btn_frame, text="Excluir", command=self.delete_servico) self.btn_delete_servico.grid(row=0, column=2, padx=5) self.btn_delete_servico.state(['disabled']) self.btn_clear_servico = tk.Buton(btn_frame, text="Limpar", command=self.clear_servico_form) self.btn_clear_servico.grid(row=0, column=3, padx=5) # Treeview listing serviços list_frame = tk.LabelFrame(frame, text="Serviços Cadastrados", padding=10) list_frame.pack(fill='both', expand=True, padx=10, pady=10) columns = ("id", "cliente_id", "cliente_nome", "descricao", "valor", "status") # adding cliente_id as a hidden column (for mapping and selecting) self.tree_servicos = tk.Treeview(list_frame, columns=columns, show='headings', selectmode='browse') self.tree_servicos.heading("id", text="ID") self.tree_servicos.column("id", width=40, anchor='center') self.tree_servicos.heading("cliente_nome", text="Cliente") self.tree_servicos.column("cliente_nome", width=200) self.tree_servicos.heading("descricao", text="Descrição") self.tree_servicos.column("descricao", width=300) self.tree_servicos.heading("valor", text="Valor (R$)") self.tree_servicos.column("valor", width=80, anchor='center') self.tree_servicos.heading("status", text="Status") self.tree_servicos.column("status", width=120, anchor='center') # Hide cliente_id column self.tree_servicos.column("cliente_id", width=0, stretch=False) self.tree_servicos.heading("cliente_id", text="cliente_id", anchor='center') self.tree_servicos.pack(fill='both', expand=True) self.tree_servicos.bind('<<TreeviewSelect>>', self.on_servico_select) self.load_cliente_combobox() self.load_servicos() def load_cliente_combobox(self): clientes = get_clientes() self.clientes_map = {f"{nome} (ID: {cid})": cid for cid, nome, _, _ in clientes} self.combo_servico_cliente['values'] = list(self.clientes_map.keys()) self.servico_cliente_var.set('') # Reset combobox def load_servicos(self): for i in self.tree_servicos.get_children(): self.tree_servicos.delete(i) for servico in get_servicos(): sid, cliente_id, cliente_nome, descricao, valor, status = servico valor_str = f"{valor:.2f}" # inserir clientes em arvore galera self.tree_servicos.insert('', 'end', values=(sid, cliente_id, cliente_nome, descricao, valor_str, status)) self.clear_servico_form() def add_servico(self): cliente_str = self.servico_cliente_var.get() descricao = self.servico_descricao_var.get().strip() valor_str = self.servico_valor_var.get().strip() status = self.servico_status_var.get() if not cliente_str or not descricao or not valor_str or not status: messagebox.showwarning("Validação", "Todos os campos com * são obrigatórios.") return try: valor = float(valor_str.replace(',', '.')) except ValueError: messagebox.showwarning("Validação", "Valor inválido. Por favor, insira um número válido.") return cliente_id = self.clientes_map.get(cliente_str) add_servico(cliente_id, descricao, valor, status) messagebox.showinfo("Sucesso", "Serviço adicionado com sucesso.") self.load_servicos() def on_servico_select(self, event): selected = self.tree_servicos.focus() if not selected: return values = self.tree_servicos.item(selected, 'values') self.selected_servico_id = values[0] cliente_id = values[1] cliente_nome = values[2] descricao = values[3] valor = values[4] status = values[5] # Set form fields # Find cliente string key by cliente_id using reverse lookup for k, v in self.clientes_map.items(): if v == cliente_id: self.servico_cliente_var.set(k) break self.servico_descricao_var.set(descricao) self.servico_valor_var.set(valor) self.servico_status_var.set(status) self.btn_update_servico.state(['!disabled']) self.btn_delete_servico.state(['!disabled']) self.btn_add_servico.state(['disabled']) def update_servico(self): if not hasattr(self, 'selected_servico_id'): return cliente_str = self.servico_cliente_var.get() descricao = self.servico_descricao_var.get().strip() valor_str = self.servico_valor_var.get().strip() status = self.servico_status_var.get() if not cliente_str or not descricao or not valor_str or not status: messagebox.showwarning("Validação", "Todos os campos com * são obrigatórios.") return try: valor = float(valor_str.replace(',', '.')) except ValueError: messagebox.showwarning("Validação", "Valor inválido. Por favor, insira um número válido.") return cliente_id = self.clientes_map.get(cliente_str) update_servico(self.selected_servico_id, cliente_id, descricao, valor, status) messagebox.showinfo("Sucesso", "Serviço atualizado com sucesso.") self.load_servicos() def delete_servico(self): if not hasattr(self, 'selected_servico_id'): return confirm = messagebox.askyesno("Confirmação", "Deseja realmente excluir este serviço?") if confirm: delete_servico(self.selected_servico_id) messagebox.showinfo("Sucesso", "Serviço excluído com sucesso.") self.load_servicos() def clear_servico_form(self): self.servico_cliente_var.set('') self.servico_descricao_var.set('') self.servico_valor_var.set('') self.servico_status_var.set("Recebido") self.btn_update_servico.state(['disabled']) self.btn_delete_servico.state(['disabled']) self.btn_add_servico.state(['!disabled']) if hasattr(self, 'selected_servico_id'): del self.selected_servico_id # Also reset selection in tree self.tree_servicos.selection_remove(self.tree_servicos.selection()) def main(): create_database_and_tables() root = tk.Tk() app = LojaConsertoApp(root) root.mainloop() if __name__ == "__main__" main()

Stuck with a problem? Got Error? Ask ChatGPT!