Advertisement
MizunoBrasil

Gerenciador de Senhas v. 4

May 14th, 2024
782
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.83 KB | None | 0 0
  1. import tkinter as tk
  2. from tkinter import ttk, messagebox
  3. import threading
  4. import os
  5. import pyperclip
  6. import webbrowser
  7.  
  8. class Application(tk.Tk):
  9.     def __init__(self):
  10.         super().__init__()
  11.  
  12.         self.title("Gerenciador de Senhas - Filtre os dados por Site ou por Login")
  13.         self.geometry("1000x600")
  14.  
  15.         self.sort_order_site = "asc"  # Variável de controle para rastrear o estado da ordenação para a coluna "Site"
  16.         self.sort_order_login = "asc"  # Variável de controle para rastrear o estado da ordenação para a coluna "Login"
  17.  
  18.         self.create_widgets()
  19.         self.create_menu()  # Adicionar o menu Arquivo
  20.  
  21.         # Adicionar rótulo com data no canto inferior esquerdo
  22.         self.date_label = ttk.Label(self, text="Mizuno - 06/05/2024")
  23.         self.date_label.place(x=10, y=self.winfo_height() - 30)
  24.  
  25.         # Centralizar janela principal
  26.         self.center_window()
  27.  
  28.     def create_widgets(self):
  29.         self.tree = ttk.Treeview(self, columns=("Site", "URL", "Login", "Senha"), show="headings")
  30.         self.tree.heading("Site", text="Site", command=self.sort_sites)  # Vinculando a função de ordenação para a coluna "Site"
  31.         self.tree.heading("URL", text="URL")
  32.         self.tree.heading("Login", text="Login", command=self.sort_login)  # Vinculando a função de ordenação para a coluna "Login"
  33.         self.tree.heading("Senha", text="Senha")
  34.         self.tree.pack(pady=10, side="left", fill="both", expand=True)
  35.  
  36.         # Adicionando barra de rolagem vertical
  37.         scrollbar = ttk.Scrollbar(self, orient="vertical", command=self.tree.yview)
  38.         scrollbar.pack(side="right", fill="y")
  39.         self.tree.configure(yscrollcommand=scrollbar.set)
  40.  
  41.         self.refresh_button = ttk.Button(self, text="Atualizar", command=self.refresh_tree)
  42.         self.refresh_button.pack()
  43.  
  44.         self.add_button = ttk.Button(self, text="Adicionar", command=self.add_entry)
  45.         self.add_button.pack()
  46.  
  47.         self.edit_button = ttk.Button(self, text="Editar", command=self.edit_entry)
  48.         self.edit_button.pack()
  49.  
  50.         self.delete_button = ttk.Button(self, text="Excluir", command=self.confirm_delete)
  51.         self.delete_button.pack()
  52.  
  53.         # Carregar dados do arquivo ao iniciar
  54.         self.load_data()
  55.  
  56.         # Adicionar menu de contexto à árvore
  57.         self.tree.bind("<Button-3>", self.popup_menu)
  58.  
  59.         # Adicionar evento de duplo clique para abrir a URL no navegador padrão
  60.         self.tree.bind("<Double-1>", self.open_url)
  61.  
  62.     def create_menu(self):
  63.         # Criar menu "Arquivo"
  64.         self.menu_bar = tk.Menu(self)
  65.         self.file_menu = tk.Menu(self.menu_bar, tearoff=0)
  66.         self.file_menu.add_command(label="Sobre", command=self.show_about_dialog)  # Adicionar a opção "Sobre"
  67.         self.file_menu.add_separator()
  68.         self.file_menu.add_command(label="Sair", command=self.quit_app)  # Adicionar a opção "Sair"
  69.         self.menu_bar.add_cascade(label="Arquivo", menu=self.file_menu)
  70.         self.config(menu=self.menu_bar)
  71.  
  72.     def open_url(self, event):
  73.         if self.tree.selection():
  74.             item = self.tree.selection()[0]
  75.             url = self.tree.item(item, "values")[1]  # Index 1 representa a coluna da URL
  76.             webbrowser.open(url)
  77.  
  78.     def center_window(self):
  79.         self.update_idletasks()
  80.         width = self.winfo_width()
  81.         height = self.winfo_height()
  82.         x = (self.winfo_screenwidth() - width) // 2
  83.         y = (self.winfo_screenheight() - height) // 2
  84.         self.geometry('{}x{}+{}+{}'.format(width, height, x, y))
  85.  
  86.     def load_data(self):
  87.         if os.path.exists("dados.txt"):
  88.             with open("dados.txt", "r") as f:
  89.                 for line in f:
  90.                     data = line.strip().split(",")
  91.                     self.tree.insert("", "end", values=data)
  92.  
  93.     def save_data(self):
  94.         with open("dados.txt", "w") as f:
  95.             for item in self.tree.get_children():
  96.                 values = self.tree.item(item, "values")
  97.                 f.write(",".join(values) + "\n")
  98.  
  99.     def refresh_tree(self):
  100.         for item in self.tree.get_children():
  101.             self.tree.delete(item)
  102.         self.load_data()
  103.  
  104.     def add_entry(self):
  105.         AddEntryWindow(self)
  106.  
  107.     def edit_entry(self):
  108.         try:
  109.             item = self.tree.selection()[0]
  110.             values = self.tree.item(item, "values")
  111.             EditEntryWindow(self, values)
  112.         except IndexError:
  113.             messagebox.showerror("Erro", "Selecione um registro para editar.")
  114.  
  115.     def delete_entry(self):
  116.         selected_item = self.tree.selection()[0]
  117.         self.tree.delete(selected_item)
  118.         self.save_data()
  119.  
  120.     def confirm_delete(self):
  121.         try:
  122.             if messagebox.askyesno("Confirmar", "Tem certeza que deseja excluir este registro?"):
  123.                 self.delete_entry()
  124.         except IndexError:
  125.             messagebox.showerror("Erro", "Selecione um registro para excluir.")
  126.  
  127.     def popup_menu(self, event):
  128.         popup_menu = tk.Menu(self, tearoff=0)
  129.         popup_menu.add_command(label="Copiar URL", command=lambda: self.copy_to_clipboard(1))
  130.         popup_menu.add_command(label="Copiar Login", command=lambda: self.copy_to_clipboard(2))
  131.         popup_menu.add_command(label="Copiar Senha", command=lambda: self.copy_to_clipboard(3))
  132.         popup_menu.post(event.x_root, event.y_root)
  133.  
  134.     def copy_to_clipboard(self, column_index):
  135.         item = self.tree.selection()[0]
  136.         value = self.tree.item(item, "values")[column_index]
  137.         pyperclip.copy(value)
  138.    
  139.     def sort_sites(self):
  140.         # Função para classificar os sites em ordem alfabética ascendente ou descendente
  141.         items = self.tree.get_children("")
  142.         if self.sort_order_site == "asc":
  143.             sorted_items = sorted(items, key=lambda x: self.tree.item(x, "values")[0])
  144.             self.sort_order_site = "desc"
  145.         else:
  146.             sorted_items = sorted(items, key=lambda x: self.tree.item(x, "values")[0], reverse=True)
  147.             self.sort_order_site = "asc"
  148.         for item in sorted_items:
  149.             self.tree.move(item, "", "end")
  150.  
  151.     def sort_login(self):
  152.         # Função para classificar os logins em ordem alfabética ascendente ou descendente
  153.         items = self.tree.get_children("")
  154.         if self.sort_order_login == "asc":
  155.             sorted_items = sorted(items, key=lambda x: self.tree.item(x, "values")[2])
  156.             self.sort_order_login = "desc"
  157.         else:
  158.             sorted_items = sorted(items, key=lambda x: self.tree.item(x, "values")[2], reverse=True)
  159.             self.sort_order_login = "asc"
  160.         for item in sorted_items:
  161.             self.tree.move(item, "", "end")
  162.  
  163.     def show_about_dialog(self):
  164.         messagebox.showinfo("Sobre", "Última atualização: 15/05/2024, by Mizuno")
  165.  
  166.     def quit_app(self):
  167.         self.destroy()
  168.  
  169.  
  170. class AddEntryWindow(tk.Toplevel):
  171.     def __init__(self, master):
  172.         super().__init__(master)
  173.  
  174.         self.title("Adicionar Registro")
  175.         self.geometry("300x250")
  176.  
  177.         self.site_label = ttk.Label(self, text="Site:")
  178.         self.site_label.pack()
  179.         self.site_entry = ttk.Entry(self)
  180.         self.site_entry.pack()
  181.  
  182.         self.url_label = ttk.Label(self, text="URL:")
  183.         self.url_label.pack()
  184.         self.url_entry = ttk.Entry(self)
  185.         self.url_entry.pack()
  186.  
  187.         self.login_label = ttk.Label(self, text="Login:")
  188.         self.login_label.pack()
  189.         self.login_entry = ttk.Entry(self)
  190.         self.login_entry.pack()
  191.  
  192.         self.password_label = ttk.Label(self, text="Senha:")
  193.         self.password_label.pack()
  194.         self.password_entry = ttk.Entry(self, show="*")
  195.         self.password_entry.pack()
  196.  
  197.         self.add_button = ttk.Button(self, text="Adicionar", command=self.add_entry)
  198.         self.add_button.pack()
  199.  
  200.         # Centralizar janela de adicionar registro
  201.         self.center_window()
  202.  
  203.     def center_window(self):
  204.         self.update_idletasks()
  205.         width = self.winfo_width()
  206.         height = self.winfo_height()
  207.         x = (self.winfo_screenwidth() - width) // 2
  208.         y = (self.winfo_screenheight() - height) // 2
  209.         self.geometry('{}x{}+{}+{}'.format(width, height, x, y))
  210.  
  211.     def add_entry(self):
  212.         site = self.site_entry.get()
  213.         url = self.url_entry.get()
  214.         login = self.login_entry.get()
  215.         password = self.password_entry.get()
  216.  
  217.         if site and url and login and password:
  218.             self.master.tree.insert("", "end", values=(site, url, login, password))
  219.             self.master.save_data()
  220.             self.destroy()
  221.         else:
  222.             messagebox.showerror("Erro", "Preencha todos os campos.")
  223.  
  224.  
  225. class EditEntryWindow(AddEntryWindow):
  226.     def __init__(self, master, values):
  227.         super().__init__(master)
  228.  
  229.         self.title("Editar Registro")
  230.  
  231.         self.site_entry.insert(0, values[0])
  232.         self.url_entry.insert(0, values[1])
  233.         self.login_entry.insert(0, values[2])
  234.         self.password_entry.insert(0, values[3])
  235.  
  236.         self.add_button.config(text="Salvar")
  237.         self.add_button.config(command=self.save_entry)
  238.  
  239.         self.values = values
  240.  
  241.         # Centralizar janela de editar registro
  242.         self.center_window()
  243.  
  244.     def save_entry(self):
  245.         site = self.site_entry.get()
  246.         url = self.url_entry.get()
  247.         login = self.login_entry.get()
  248.         password = self.password_entry.get()
  249.  
  250.         if site and url and login and password:
  251.             self.master.tree.item(self.master.tree.selection(), values=(site, url, login, password))
  252.             self.master.save_data()
  253.             self.destroy()
  254.         else:
  255.             messagebox.showerror("Erro", "Preencha todos os campos.")
  256.  
  257.  
  258. def main():
  259.     app = Application()
  260.     app.mainloop()
  261.  
  262.  
  263. if __name__ == "__main__":
  264.     main()
  265.  
Tags: python windows
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement