Hi! Could we please enable some services and cookies to improve your experience and our website?
No, thanks.
Okay!
SQLize
Online
/
PHPize Online
/
SQLtest Online
A
A
A
Share code
Donate
Blog
Popular
FAQ
Donate
A
A
A
Share
Blog
Popular
FAQ
Online Sandbox for SQL and PHP: Write, Run, Test, and Share SQL Queries and PHP Code
SQL code:
Upload
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()
SQL
Server:
MySQL 8.0
MySQL 8.0 Sakila (ReadOnly)
MySQL 9.3.0
MariaDB 11.4
MariaDB 11.8
MariaDB 10
MariaDB 10 Sakila (ReadOnly)
SQLite 3
SQLite 3 Preloaded
PostgreSQL 10 Bookings (ReadOnly)
PostgreSQL 13
PostgreSQL 14
PostgreSQL 15
PostgreSQL 16
PostgreSQL 17
MS SQL Server 2017
MS SQL Server 2019
MS SQL Server 2022
MS SQL Server 2022 AdventureWorks (ReadOnly)
Firebird 4.0
Firebird 4.0 (Employee)
Oracle Database 19c (HR)
Oracle Database 21c
Oracle Database 23c Free
SOQOL
Version
ER Diagram
Preserve result
Stuck with a problem?
Got Error?
Ask ChatGPT!
Result:
Copy
Clear