Advertisement
MizunoBrasil

Lista de Compromissos

Feb 4th, 2025
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.21 KB | None | 0 0
  1. import sqlite3
  2. import tkinter as tk
  3. from tkinter import messagebox, ttk, filedialog
  4. import re
  5. import shutil
  6. import os
  7. import sys
  8.  
  9. # Conectar ao banco de dados SQLite
  10. conexao = sqlite3.connect("agenda.db")
  11. cursor = conexao.cursor()
  12.  
  13. # Criar a tabela se ela não existir
  14. cursor.execute('''
  15. CREATE TABLE IF NOT EXISTS compromissos (
  16.    id INTEGER PRIMARY KEY AUTOINCREMENT,
  17.    titulo TEXT NOT NULL,
  18.    descricao TEXT,
  19.    data TEXT NOT NULL,
  20.    hora TEXT NOT NULL
  21. )
  22. ''')
  23. conexao.commit()
  24.  
  25. def extrair_data_hora(descricao):
  26.     padrao_data = re.search(r'\b(\d{2}/\d{2}/\d{4})\b', descricao)
  27.     padrao_hora = re.search(r'\b(\d{2}:\d{2})\b', descricao)
  28.    
  29.     if not padrao_data or not padrao_hora:
  30.         messagebox.showerror("Erro", "Data ou horário inválidos! Certifique-se de informar a data no formato DD/MM/AAAA e o horário no formato HH:MM dentro da descrição.")
  31.         return None, None
  32.  
  33.     data = padrao_data.group(0)
  34.     hora = padrao_hora.group(0)
  35.     return data, hora
  36.  
  37. def adicionar_compromisso():
  38.     titulo = entrada_titulo.get()
  39.     descricao = entrada_descricao.get("1.0", tk.END).strip()
  40.    
  41.     if not titulo or not descricao:
  42.         messagebox.showerror("Erro", "Por favor, preencha todos os campos obrigatórios.")
  43.         return
  44.  
  45.     data_compromisso, hora_compromisso = extrair_data_hora(descricao)
  46.     if not data_compromisso or not hora_compromisso:
  47.         return
  48.  
  49.     cursor.execute("INSERT INTO compromissos (titulo, descricao, data, hora) VALUES (?, ?, ?, ?)",
  50.                    (titulo, descricao, data_compromisso, hora_compromisso))
  51.     conexao.commit()
  52.     messagebox.showinfo("Sucesso", "Compromisso adicionado com sucesso!")
  53.     limpar_campos()
  54.     carregar_compromissos()
  55.  
  56. def carregar_compromissos():
  57.     for item in tabela.get_children():
  58.         tabela.delete(item)
  59.  
  60.     cursor.execute("SELECT id, titulo, data, hora FROM compromissos")
  61.     for row in cursor.fetchall():
  62.         tabela.insert("", tk.END, values=row)
  63.  
  64. def exibir_detalhes(event):
  65.     item_selecionado = tabela.selection()
  66.     if not item_selecionado:
  67.         return
  68.  
  69.     compromisso_id = tabela.item(item_selecionado[0], "values")[0]
  70.     cursor.execute("SELECT * FROM compromissos WHERE id = ?", (compromisso_id,))
  71.     compromisso = cursor.fetchone()
  72.  
  73.     if compromisso:
  74.         janela_detalhes = tk.Toplevel()
  75.         janela_detalhes.title("Detalhes do Compromisso")
  76.         largura = 600
  77.         altura = 400
  78.         largura_tela = janela_detalhes.winfo_screenwidth()
  79.         altura_tela = janela_detalhes.winfo_screenheight()
  80.         pos_x = (largura_tela // 2) - (largura // 2)
  81.         pos_y = (altura_tela // 2) - (altura // 2)
  82.         janela_detalhes.geometry(f"{largura}x{altura}+{pos_x}+{pos_y}")
  83.  
  84.         tk.Label(janela_detalhes, text="Título:", font=("Arial", 10, "bold")).grid(row=0, column=0, sticky="w", padx=10, pady=5)
  85.         entrada_titulo_editar = tk.Entry(janela_detalhes, width=70, font=("Arial", 10))
  86.         entrada_titulo_editar.insert(0, compromisso[1])
  87.         entrada_titulo_editar.grid(row=0, column=1, padx=10, pady=5, sticky="w")
  88.  
  89.         tk.Label(janela_detalhes, text="Descrição:", font=("Arial", 10, "bold")).grid(row=1, column=0, sticky="nw", padx=10, pady=5)
  90.         entrada_descricao_editar = tk.Text(janela_detalhes, width=70, height=10, font=("Arial", 10))
  91.         entrada_descricao_editar.insert("1.0", compromisso[2])
  92.         entrada_descricao_editar.grid(row=1, column=1, padx=10, pady=5, sticky="w")
  93.  
  94.         tk.Label(janela_detalhes, text="Data:", font=("Arial", 10, "bold")).grid(row=2, column=0, sticky="w", padx=10, pady=5)
  95.         tk.Label(janela_detalhes, text=compromisso[3], font=("Arial", 10)).grid(row=2, column=1, sticky="w", padx=10, pady=5)
  96.  
  97.         tk.Label(janela_detalhes, text="Hora:", font=("Arial", 10, "bold")).grid(row=3, column=0, sticky="w", padx=10, pady=5)
  98.         tk.Label(janela_detalhes, text=compromisso[4], font=("Arial", 10)).grid(row=3, column=1, sticky="w", padx=10, pady=5)
  99.  
  100.         def salvar_edicao():
  101.             novo_titulo = entrada_titulo_editar.get()
  102.             nova_descricao = entrada_descricao_editar.get("1.0", tk.END).strip()
  103.  
  104.             if not novo_titulo or not nova_descricao:
  105.                 messagebox.showerror("Erro", "Todos os campos devem ser preenchidos.")
  106.                 return
  107.  
  108.             nova_data, nova_hora = extrair_data_hora(nova_descricao)
  109.             if not nova_data or not nova_hora:
  110.                 return
  111.  
  112.             cursor.execute("UPDATE compromissos SET titulo = ?, descricao = ?, data = ?, hora = ? WHERE id = ?",
  113.                            (novo_titulo, nova_descricao, nova_data, nova_hora, compromisso[0]))
  114.             conexao.commit()
  115.             messagebox.showinfo("Sucesso", "Compromisso atualizado com sucesso!")
  116.             carregar_compromissos()
  117.             janela_detalhes.destroy()
  118.  
  119.         botoes_frame = tk.Frame(janela_detalhes)
  120.         botoes_frame.grid(row=4, column=0, columnspan=2, pady=15)
  121.  
  122.         botao_salvar = tk.Button(botoes_frame, text="Salvar", command=salvar_edicao, width=12, bg="lightblue", font=("Arial", 10, "bold"))
  123.         botao_salvar.pack(side="left", padx=10)
  124.  
  125.         botao_fechar = tk.Button(botoes_frame, text="Fechar", command=janela_detalhes.destroy, width=12, bg="lightgrey", font=("Arial", 10))
  126.         botao_fechar.pack(side="left", padx=10)
  127.  
  128. def exportar_para_html():
  129.     cursor.execute("SELECT titulo, descricao, data, hora FROM compromissos")
  130.     compromissos = cursor.fetchall()
  131.  
  132.     html_content = """
  133.    <!DOCTYPE html>
  134.    <html lang="pt-BR">
  135.    <head>
  136.        <meta charset="UTF-8">
  137.        <meta name="viewport" content="width=device-width, initial-scale=1.0">
  138.        <title>Compromissos</title>
  139.        <style>
  140.            body {
  141.                font-family: Arial, sans-serif;
  142.                background-color: #f4f4f9;
  143.                padding: 20px;
  144.            }
  145.            h1 {
  146.                text-align: center;
  147.            }
  148.            table {
  149.                width: 100%;
  150.                border-collapse: collapse;
  151.            }
  152.            th, td {
  153.                padding: 10px;
  154.                border: 1px solid #ddd;
  155.                text-align: left;
  156.            }
  157.            th {
  158.                background-color: #007bff;
  159.                color: white;
  160.            }
  161.            tr:nth-child(even) {
  162.                background-color: #f2f2f2;
  163.            }
  164.        </style>
  165.    </head>
  166.    <body>
  167.        <h1>Lista de Compromissos</h1>
  168.        <table>
  169.            <tr>
  170.                <th>Título</th>
  171.                <th>Descrição</th>
  172.                <th>Data</th>
  173.                <th>Hora</th>
  174.            </tr>
  175.    """
  176.  
  177.     for compromisso in compromissos:
  178.         html_content += f"""
  179.            <tr>
  180.                <td>{compromisso[0]}</td>
  181.                <td>{compromisso[1]}</td>
  182.                <td>{compromisso[2]}</td>
  183.                <td>{compromisso[3]}</td>
  184.            </tr>
  185.        """
  186.  
  187.     html_content += """
  188.        </table>
  189.    </body>
  190.    </html>
  191.    """
  192.  
  193.     with open("compromissos.html", "w", encoding="utf-8") as f:
  194.         f.write(html_content)
  195.  
  196.     messagebox.showinfo("Sucesso", "Compromissos exportados para 'compromissos.html'.")
  197.  
  198. def remover_compromisso():
  199.     item_selecionado = tabela.selection()
  200.     if not item_selecionado:
  201.         messagebox.showwarning("Aviso", "Por favor, selecione um compromisso para remover.")
  202.         return
  203.  
  204.     confirmacao = messagebox.askyesno("Confirmação", "Tem certeza de que deseja remover o compromisso selecionado?")
  205.     if confirmacao:
  206.         compromisso_id = tabela.item(item_selecionado[0], "values")[0]
  207.         cursor.execute("DELETE FROM compromissos WHERE id = ?", (compromisso_id,))
  208.         conexao.commit()
  209.         carregar_compromissos()
  210.         messagebox.showinfo("Sucesso", "Compromisso removido com sucesso.")
  211.  
  212. def limpar_campos():
  213.     entrada_titulo.delete(0, tk.END)
  214.     entrada_descricao.delete("1.0", tk.END)
  215.  
  216. def fazer_backup():
  217.     destino = filedialog.asksaveasfilename(defaultextension=".db", filetypes=[("SQLite Database", "*.db")])
  218.     if destino:
  219.         shutil.copy("agenda.db", destino)
  220.         messagebox.showinfo("Sucesso", f"Backup realizado com sucesso em: {destino}")
  221.  
  222. def restaurar_backup():
  223.     origem = filedialog.askopenfilename(filetypes=[("SQLite Database", "*.db")])
  224.     if origem and messagebox.askyesno("Confirmação", "Tem certeza de que deseja restaurar este backup? Isso substituirá os dados atuais."):
  225.         conexao.close()
  226.         os.remove("agenda.db")
  227.         shutil.copy(origem, "agenda.db")
  228.         messagebox.showinfo("Sucesso", "Backup restaurado com sucesso!")
  229.         os.execl(sys.executable, sys.executable, *sys.argv)  # Reiniciar a aplicação
  230.  
  231. janela = tk.Tk()
  232. janela.title("Lista de Compromissos")
  233. largura = 800
  234. altura = 500
  235. largura_tela = janela.winfo_screenwidth()
  236. altura_tela = janela.winfo_screenheight()
  237. pos_x = (largura_tela // 2) - (largura // 2)
  238. pos_y = (altura_tela // 2) - (altura // 2)
  239. janela.geometry(f"{largura}x{altura}+{pos_x}+{pos_y}")
  240.  
  241. tk.Label(janela, text="Título:", font=("Arial", 10, "bold")).grid(row=0, column=0, sticky="w", padx=5, pady=5)
  242. entrada_titulo = tk.Entry(janela, width=70, font=("Arial", 10))
  243. entrada_titulo.grid(row=0, column=1, padx=5, pady=5, sticky="w")
  244.  
  245. tk.Label(janela, text="Descrição:", font=("Arial", 10, "bold")).grid(row=1, column=0, sticky="nw", padx=5, pady=5)
  246. entrada_descricao = tk.Text(janela, width=70, height=5, font=("Arial", 10))
  247. entrada_descricao.grid(row=1, column=1, padx=5, pady=5)
  248.  
  249. botoes_frame_principal = tk.Frame(janela)
  250. botoes_frame_principal.grid(row=2, column=1, pady=10, sticky="w")
  251.  
  252. botao_adicionar = tk.Button(botoes_frame_principal, text="Adicionar", command=adicionar_compromisso, width=12, bg="lightblue", font=("Arial", 10, "bold"))
  253. botao_adicionar.pack(side="left", padx=5)
  254.  
  255. botao_remover = tk.Button(botoes_frame_principal, text="Remover", command=remover_compromisso, width=12, bg="lightcoral", font=("Arial", 10, "bold"))
  256. botao_remover.pack(side="left", padx=5)
  257.  
  258. botao_exportar = tk.Button(botoes_frame_principal, text="Exportar HTML", command=exportar_para_html, width=12, bg="lightgreen", font=("Arial", 10, "bold"))
  259. botao_exportar.pack(side="left", padx=5)
  260.  
  261. botao_backup = tk.Button(botoes_frame_principal, text="Backup", command=fazer_backup, width=12, bg="lightyellow", font=("Arial", 10, "bold"))
  262. botao_backup.pack(side="left", padx=5)
  263.  
  264. botao_restaurar = tk.Button(botoes_frame_principal, text="Restaurar", command=restaurar_backup, width=12, bg="lightpink", font=("Arial", 10, "bold"))
  265. botao_restaurar.pack(side="left", padx=5)
  266.  
  267. tabela = ttk.Treeview(janela, columns=("ID", "Título", "Data", "Hora"), show="headings")
  268. tabela.heading("ID", text="ID")
  269. tabela.heading("Título", text="Título")
  270. tabela.heading("Data", text="Data")
  271. tabela.heading("Hora", text="Hora")
  272. tabela.column("ID", width=30)
  273. tabela.column("Título", width=300)
  274. tabela.column("Data", width=100)
  275. tabela.column("Hora", width=70)
  276. tabela.grid(row=3, column=0, columnspan=2, pady=10, padx=5, sticky="nsew")
  277.  
  278. janela.grid_rowconfigure(3, weight=1)
  279. janela.grid_columnconfigure(1, weight=1)
  280.  
  281. tabela.bind("<Double-1>", exibir_detalhes)
  282. carregar_compromissos()
  283. janela.mainloop()
  284. conexao.close()
  285.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement