· last year · Sep 16, 2024, 04:00 AM
1import tkinter as tk
2from tkinter import ttk, messagebox
3import sqlite3
4import pyperclip
5import webbrowser
6from tkcalendar import DateEntry # Para o calendário
7from reportlab.lib.pagesizes import letter
8from reportlab.pdfgen import canvas
9
10
11class Application(tk.Tk):
12 def __init__(self):
13 super().__init__()
14 self.title("Gerenciador de Filmes")
15 self.geometry("1000x600")
16 self.init_db()
17 self.create_widgets()
18 self.create_menu()
19 self.center_window()
20
21 def create_widgets(self):
22 self.search_var = tk.StringVar()
23 self.search_entry = ttk.Entry(self, textvariable=self.search_var)
24 self.search_entry.pack(pady=(0, 10))
25 self.search_button = ttk.Button(self, text="Pesquisar", command=self.search_records)
26 self.search_button.pack(pady=(0, 10))
27
28 # Atualizado: Removido o campo "Sinopse"
29 self.tree = ttk.Treeview(self, columns=("Nome", "Gênero", "URL", "Data"), show="headings")
30 self.tree.heading("Nome", text="Nome")
31 self.tree.heading("Gênero", text="Gênero")
32 self.tree.heading("URL", text="URL")
33 self.tree.heading("Data", text="Data")
34 self.tree.pack(pady=10, side="left", fill="both", expand=True)
35
36 scrollbar = ttk.Scrollbar(self, orient="vertical", command=self.tree.yview)
37 scrollbar.pack(side="right", fill="y")
38 self.tree.configure(yscrollcommand=scrollbar.set)
39
40 self.add_button = ttk.Button(self, text="Adicionar Filme", command=self.add_entry)
41 self.add_button.pack()
42 self.edit_button = ttk.Button(self, text="Editar Filme", command=self.edit_entry)
43 self.edit_button.pack()
44 self.delete_button = ttk.Button(self, text="Excluir Filme", command=self.confirm_delete)
45 self.delete_button.pack()
46 self.pdf_button = ttk.Button(self, text="Exportar PDF", command=self.export_to_pdf)
47 self.pdf_button.pack()
48
49 self.tree.bind("<Button-3>", self.popup_menu)
50 self.tree.bind("<Double-1>", self.open_url)
51
52 self.load_data()
53
54 def create_menu(self):
55 self.menu_bar = tk.Menu(self)
56 self.file_menu = tk.Menu(self.menu_bar, tearoff=0)
57 self.file_menu.add_command(label="Sobre", command=self.show_about_dialog)
58 self.file_menu.add_separator()
59 self.file_menu.add_command(label="Sair", command=self.quit_app)
60 self.menu_bar.add_cascade(label="Arquivo", menu=self.file_menu)
61 self.config(menu=self.menu_bar)
62
63 def init_db(self):
64 self.conn = sqlite3.connect("filmes.db")
65 self.cursor = self.conn.cursor()
66 self.cursor.execute("""
67 CREATE TABLE IF NOT EXISTS filmes (
68 id INTEGER PRIMARY KEY AUTOINCREMENT,
69 nome TEXT,
70 genero TEXT,
71 url TEXT,
72 data TEXT
73 )
74 """)
75 self.conn.commit()
76
77 def load_data(self):
78 self.cursor.execute("SELECT nome, genero, url, data FROM filmes")
79 for row in self.cursor.fetchall():
80 self.tree.insert("", "end", values=row)
81
82 def save_data(self):
83 self.cursor.execute("DELETE FROM filmes")
84 for item in self.tree.get_children():
85 values = self.tree.item(item, "values")
86 self.cursor.execute("INSERT INTO filmes (nome, genero, url, data) VALUES (?, ?, ?, ?)", values)
87 self.conn.commit()
88
89 def refresh_tree(self):
90 for item in self.tree.get_children():
91 self.tree.delete(item)
92 self.load_data()
93
94 def add_entry(self):
95 AddEntryWindow(self)
96
97 def edit_entry(self):
98 try:
99 item = self.tree.selection()[0]
100 values = self.tree.item(item, "values")
101 EditEntryWindow(self, values)
102 except IndexError:
103 messagebox.showerror("Erro", "Selecione um registro para editar.")
104
105 def delete_entry(self):
106 selected_item = self.tree.selection()[0]
107 nome = self.tree.item(selected_item, "values")[0]
108 self.cursor.execute("DELETE FROM filmes WHERE nome=?", (nome,))
109 self.conn.commit()
110 self.tree.delete(selected_item)
111
112 def confirm_delete(self):
113 try:
114 if messagebox.askyesno("Confirmar", "Tem certeza que deseja excluir este filme?"):
115 self.delete_entry()
116 except IndexError:
117 messagebox.showerror("Erro", "Selecione um registro para excluir.")
118
119 def popup_menu(self, event):
120 popup_menu = tk.Menu(self, tearoff=0)
121 popup_menu.add_command(label="Copiar URL", command=lambda: self.copy_to_clipboard(2))
122 popup_menu.post(event.x_root, event.y_root)
123
124 def copy_to_clipboard(self, column_index):
125 item = self.tree.selection()[0]
126 value = self.tree.item(item, "values")[column_index]
127 pyperclip.copy(value)
128
129 def open_url(self, event):
130 if self.tree.selection():
131 item = self.tree.selection()[0]
132 url = self.tree.item(item, "values")[2]
133 webbrowser.open(url)
134
135 def search_records(self):
136 search_term = self.search_var.get().strip().lower()
137 if not search_term:
138 messagebox.showinfo("Pesquisa", "Digite um termo de pesquisa.")
139 return
140
141 for item in self.tree.get_children():
142 self.tree.delete(item)
143
144 self.cursor.execute("""
145 SELECT nome, genero, url, data FROM filmes
146 WHERE lower(nome) LIKE ? OR lower(genero) LIKE ?
147 """, ('%' + search_term + '%', '%' + search_term + '%'))
148
149 found = False
150 for row in self.cursor.fetchall():
151 self.tree.insert("", "end", values=row)
152 found = True
153
154 if not found:
155 messagebox.showinfo("Pesquisa", "Nenhum registro correspondente encontrado.")
156 self.refresh_tree()
157
158 def export_to_pdf(self):
159 file_name = "filmes_cadastrados.pdf"
160 c = canvas.Canvas(file_name, pagesize=letter)
161 c.setFont("Helvetica", 10)
162 y_position = 750
163 for item in self.tree.get_children():
164 values = self.tree.item(item, "values")
165 c.drawString(100, y_position, f"Nome: {values[0]}, Gênero: {values[1]}, Data: {values[3]}")
166 y_position -= 20
167 c.save()
168 messagebox.showinfo("Exportação de dados", f"Arquivo {file_name} foi gerado com sucesso.")
169
170 def show_about_dialog(self):
171 messagebox.showinfo("Sobre", "Gerenciador de Filmes v1.0")
172
173 def quit_app(self):
174 self.conn.close()
175 self.destroy()
176
177 def center_window(self):
178 self.update_idletasks()
179 width = self.winfo_width()
180 height = self.winfo_height()
181 x = (self.winfo_screenwidth() - width) // 2
182 y = (self.winfo_screenheight() - height) // 2
183 self.geometry(f'{width}x{height}+{x}+{y}')
184
185
186class AddEntryWindow(tk.Toplevel):
187 def __init__(self, parent):
188 super().__init__(parent)
189 self.title("Adicionar Filme")
190 self.geometry("400x300")
191 self.create_widgets()
192 self.center_window()
193
194 def create_widgets(self):
195 self.nome_label = ttk.Label(self, text="Nome:")
196 self.nome_label.pack(pady=5)
197 self.nome_entry = ttk.Entry(self, width=50) # Aumentado
198 self.nome_entry.pack(pady=5)
199
200 self.genero_label = ttk.Label(self, text="Gênero:")
201 self.genero_label.pack(pady=5)
202 self.genero_entry = ttk.Entry(self, width=50) # Aumentado
203 self.genero_entry.pack(pady=5)
204
205 self.url_label = ttk.Label(self, text="URL:")
206 self.url_label.pack(pady=5)
207 self.url_entry = ttk.Entry(self, width=50) # Aumentado
208 self.url_entry.pack(pady=5)
209
210 self.data_label = ttk.Label(self, text="Data:")
211 self.data_label.pack(pady=5)
212 self.data_entry = DateEntry(self, date_pattern='dd/mm/yyyy')
213 self.data_entry.pack(pady=5)
214
215 self.save_button = ttk.Button(self, text="Salvar", command=self.save_entry)
216 self.save_button.pack(pady=20)
217
218 def center_window(self):
219 self.update_idletasks()
220 width = self.winfo_width()
221 height = self.winfo_height()
222 x = (self.winfo_screenwidth() - width) // 2
223 y = (self.winfo_screenheight() - height) // 2
224 self.geometry(f'{width}x{height}+{x}+{y}')
225
226 def save_entry(self):
227 nome = self.nome_entry.get().strip()
228 genero = self.genero_entry.get().strip()
229 url = self.url_entry.get().strip()
230 data = self.data_entry.get()
231 if nome and genero and url and data:
232 self.master.cursor.execute("INSERT INTO filmes (nome, genero, url, data) VALUES (?, ?, ?, ?)",
233 (nome, genero, url, data))
234 self.master.conn.commit()
235 self.master.refresh_tree()
236 self.destroy()
237 else:
238 messagebox.showerror("Erro", "Todos os campos devem ser preenchidos.")
239
240
241class EditEntryWindow(AddEntryWindow):
242 def __init__(self, parent, values):
243 super().__init__(parent)
244 self.values = values
245 self.fill_fields()
246
247 def fill_fields(self):
248 self.nome_entry.insert(0, self.values[0])
249 self.genero_entry.insert(0, self.values[1])
250 self.url_entry.insert(0, self.values[2])
251 self.data_entry.set_date(self.values[3])
252
253 def save_entry(self):
254 nome = self.nome_entry.get().strip()
255 genero = self.genero_entry.get().strip()
256 url = self.url_entry.get().strip()
257 data = self.data_entry.get()
258 if nome and genero and url and data:
259 selected_item = self.master.tree.selection()[0]
260 self.master.cursor.execute("""
261 UPDATE filmes
262 SET nome = ?, genero = ?, url = ?, data = ?
263 WHERE nome = ?
264 """, (nome, genero, url, data, self.values[0]))
265 self.master.conn.commit()
266 self.master.refresh_tree()
267 self.destroy()
268 else:
269 messagebox.showerror("Erro", "Todos os campos devem ser preenchidos.")
270
271
272if __name__ == "__main__":
273 app = Application()
274 app.mainloop()
275