Componentes: Gustavo N. Becker.
Objetivos: Desenvolver um sistema de controle geral.
Metodologia de desenvolvimento: Paradigma de Programação Orientada a Objetos.
import tkinter as tk
from tkinter import messagebox
import tkinter.font as tkfont
from abc import ABC, abstractmethod
import requests
class Imovel(ABC):
def __init__(self, codigo, endereco, valor):
self.__codigo = codigo
self.__endereco = endereco
self.__valor = valor
self.__disponivel = True
@property
def codigo(self):
return self.__codigo
@property
def endereco(self):
return self.__endereco
@property
def valor(self):
return self.__valor
@property
def disponivel(self):
return self.__disponivel
@disponivel.setter
def disponivel(self, status):
self.__disponivel = status
@abstractmethod
def tipo(self):
pass
def detalhes_extras(self):
return {}
def set_detalhes_extras(self, detalhes):
pass
class CasaBase(Imovel):
def __init__(self, codigo, endereco, valor):
super().__init__(codigo, endereco, valor)
self.quintal = False
self.garagem = False
self.area_servico_externo = False
self.tem_edicula = False
def detalhes_extras(self):
return {
"quintal": self.quintal,
"garagem": self.garagem,
"área_de_serviço_externo": self.area_servico_externo,
"tem_edicula": self.tem_edicula,
}
def set_detalhes_extras(self, detalhes):
self.quintal = detalhes.get("quintal", False)
self.garagem = detalhes.get("garagem", False)
self.area_servico_externo = detalhes.get("área_de_serviço_externo", False)
self.tem_edicula = detalhes.get("tem_edicula", False)
class Casa(CasaBase):
def tipo(self):
return "Casa"
class CasaGeminada(CasaBase):
def tipo(self):
return "Casa Geminada"
class Sobrado(CasaBase):
def tipo(self):
return "Sobrado"
class Edicula(Imovel):
def __init__(self, codigo, endereco, valor):
super().__init__(codigo, endereco, valor)
self.area_construida = 0.0
self.independente = False
self.banheiro_proprio = False
def tipo(self):
return "Edícula"
def detalhes_extras(self):
return {
"area_construida": self.area_construida,
"independente": self.independente,
"banheiro_proprio": self.banheiro_proprio,
}
def set_detalhes_extras(self, detalhes):
self.area_construida = detalhes.get("area_construida", 0.0)
self.independente = detalhes.get("independente", False)
self.banheiro_proprio = detalhes.get("banheiro_proprio", False)
class Apartamento(Imovel):
def tipo(self):
return "Apartamento"
class Kitnet(Imovel):
def tipo(self):
return "Kitnet/Studio"
class Flat(Imovel):
def tipo(self):
return "Flat"
class Loft(Imovel):
def tipo(self):
return "Loft"
class Cliente:
def __init__(self, cpf, nome, data_nasc="", telefone="", email="",
estado_civil="", endereco="", profissao="", renda=""):
self.cpf = cpf
self.nome = nome
self.data_nasc = data_nasc
self.telefone = telefone
self.email = email
self.estado_civil = estado_civil
self.endereco = endereco
self.profissao = profissao
self.renda = renda
@property
def cpf(self):
return self.__cpf
@cpf.setter
def cpf(self, valor):
self.__cpf = valor
@property
def nome(self):
return self.__nome
@nome.setter
def nome(self, valor):
self.__nome = valor
@property
def data_nasc(self):
return self.__data_nasc
@data_nasc.setter
def data_nasc(self, valor):
self.__data_nasc = valor
imoveis = []
clientes = []
locacoes = []
codigo_imovel = 0
detalhes_imoveis = {}
tipos_disponiveis = {
"Casa": Casa,
"Apartamento": Apartamento,
"Kitnet/Studio": Kitnet,
"Flat": Flat,
"Sobrado": Sobrado,
"Edícula": Edicula,
"Loft": Loft,
"Casa Geminada": CasaGeminada
}
def remover_imovel():
root.withdraw()
janela = tk.Toplevel()
janela.title("Remover Imóvel")
janela.geometry("600x400")
janela.protocol("WM_DELETE_WINDOW", lambda: fechar_e_reabrir_menu(janela, root))
def remover_selecionados():
selecionados = [codigo for codigo, var in checkbox_vars.items() if var.get()]
if not selecionados:
messagebox.showwarning("Aviso", "Nenhum imóvel selecionado.")
return
confirmacao = messagebox.askyesno("Confirmar Remoção",
f"Tem certeza que deseja remover {len(selecionados)} imóvel(is)?")
if confirmacao:
for codigo in selecionados:
imovel = next((i for i in imoveis if i.codigo == codigo), None)
if imovel:
imoveis.remove(imovel)
detalhes_imoveis.pop(imovel.codigo, None)
messagebox.showinfo("Sucesso", "Imóvel(is) removido(s) com sucesso.")
janela.destroy()
disponiveis = [i for i in imoveis if i.disponivel]
if not disponiveis:
tk.Label(janela, text="Nenhum imóvel disponível para remoção.").pack(pady=20)
return
tk.Label(janela, text="Marque os imóveis que deseja remover:").pack(pady=10)
frame_scroll = tk.Frame(janela)
frame_scroll.pack(fill='both', expand=True)
canvas = tk.Canvas(frame_scroll)
scrollbar = tk.Scrollbar(frame_scroll, orient="vertical", command=canvas.yview)
scroll_frame = tk.Frame(canvas)
scroll_frame.bind(
"<Configure>",
lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
)
canvas.create_window((0, 0), window=scroll_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)
canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
checkbox_vars = {}
for imovel in disponiveis:
var = tk.BooleanVar()
texto = f"Código: {imovel.codigo} | Tipo: {imovel.tipo()} | Endereço: {imovel.endereco} | Valor: R${imovel.valor:.2f}"
tk.Checkbutton(scroll_frame, text=texto, variable=var, anchor="w", justify="left").pack(fill='x', padx=10, pady=2)
checkbox_vars[imovel.codigo] = var
tk.Button(janela, text="Remover Selecionados", command=remover_selecionados).pack(pady=15)
def cadastrar_imovel():
global codigo_imovel
root.withdraw()
janela = tk.Toplevel()
janela.title("Cadastrar Imóvel")
janela.geometry("500x600")
janela.protocol("WM_DELETE_WINDOW", lambda: fechar_e_reabrir_menu(janela, root))
fonte = tkfont.Font(family="Arial", size=11)
def editar_imovel(imovel):
janela = tk.Toplevel()
janela.title(f"Editar Imóvel {imovel.codigo}")
janela.geometry("500x600")
janela.protocol("WM_DELETE_WINDOW", lambda: janela.destroy())
def ajustar_largura(entry_widget, texto):
largura_px = fonte.measure(texto + " ")
largura_caracteres = max(15, min(50, int(largura_px / fonte.measure("0"))))
entry_widget.config(width=largura_caracteres)
tk.Label(janela, text="CEP:", font=fonte).pack(pady=(10, 0))
entry_cep = tk.Entry(janela, justify='center', width=20, font=fonte)
entry_cep.pack(pady=5, padx=50)
def aplicar_mascara_cep(event=None):
cep = entry_cep.get().strip().replace("-", "")[:8]
if len(cep) > 5:
cep_formatado = f"{cep[:5]}-{cep[5:]}"
else:
cep_formatado = cep
entry_cep.delete(0, tk.END)
entry_cep.insert(0, cep_formatado)
def buscar_endereco(event=None):
cep = entry_cep.get().strip().replace("-", "")
if len(cep) != 8 or not cep.isdigit():
return
try:
response = requests.get(f"https://viacep.com.br/ws/{cep}/json/")
data = response.json()
if "erro" in data:
messagebox.showerror("Erro", "CEP não encontrado.")
return
entry_logradouro.delete(0, tk.END)
entry_logradouro.insert(0, data.get('logradouro', ''))
entry_bairro.delete(0, tk.END)
entry_bairro.insert(0, data.get('bairro', ''))
entry_cidade.delete(0, tk.END)
entry_cidade.insert(0, data.get('localidade', ''))
entry_estado.delete(0, tk.END)
entry_estado.insert(0, data.get('uf', ''))
except Exception as e:
messagebox.showerror("Erro", f"Erro ao buscar CEP: {e}")
entry_cep.bind("<KeyRelease>", lambda e: (aplicar_mascara_cep(), buscar_endereco()))
def criar_campo(janela, texto_label, largura=30, adaptavel=False):
tk.Label(janela, text=texto_label, font=fonte).pack(pady=(10, 0))
entry = tk.Entry(janela, width=largura, justify='center', font=fonte)
entry.pack(pady=5, padx=50)
if adaptavel:
entry.bind("<KeyRelease>", lambda e: ajustar_largura(entry, entry.get()))
return entry
def criar_optionmenu(janela, texto_label, var, opcoes):
tk.Label(janela, text=texto_label, font=fonte).pack(pady=(10, 0))
menu = tk.OptionMenu(janela, var, *opcoes)
menu.config(font=fonte)
menu.pack(pady=5)
return menu
entry_logradouro = criar_campo(janela, "Rua:", adaptavel=True)
entry_bairro = criar_campo(janela, "Bairro:", adaptavel=True)
entry_cidade = criar_campo(janela, "Cidade:", adaptavel=True)
entry_estado = criar_campo(janela, "Estado:", largura=5)
entry_valor = criar_campo(janela, "Valor da Locação:", adaptavel=True, largura=15)
def formatar_valor(event):
texto = entry_valor.get()
numeros = ''.join(filter(str.isdigit, texto))
if numeros == '':
entry_valor.delete(0, tk.END)
return
valor_int = int(numeros)
texto_formatado = f"{valor_int / 100:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".")
entry_valor.delete(0, tk.END)
entry_valor.insert(0, texto_formatado)
entry_valor.bind('<KeyRelease>', formatar_valor)
tipo_var = tk.StringVar(janela)
tipo_var.set("Casa")
criar_optionmenu(janela, "Tipo do Imóvel:", tipo_var, tipos_disponiveis.keys())
def salvar():
global codigo_imovel
logradouro = entry_logradouro.get().strip()
bairro = entry_bairro.get().strip()
cidade = entry_cidade.get().strip()
estado = entry_estado.get().strip()
valor = entry_valor.get().strip()
tipo = tipo_var.get()
if not logradouro or not bairro or not cidade or not estado or not valor:
messagebox.showwarning("Erro", "Todos os campos devem ser preenchidos.")
return
try:
valor_float = float(valor.replace('.', '').replace(',', '.'))
except ValueError:
messagebox.showerror("Erro", "Valor inválido.")
return
codigo_imovel += 1
codigo = f"{codigo_imovel:03d}"
endereco = f"{logradouro} - {bairro} - {cidade}/{estado}"
classe_imovel = tipos_disponiveis.get(tipo)
if not classe_imovel:
messagebox.showerror("Erro", "Tipo de imóvel inválido.")
return
imovel = classe_imovel(codigo, endereco, valor_float)
imoveis.append(imovel)
messagebox.showinfo("Sucesso", "Imóvel cadastrado com sucesso.")
janela.destroy()
abrir_detalhes_imovel(imovel)
tk.Button(janela, text="Salvar", command= salvar, font=fonte).pack(pady=15)
def abrir_detalhes_imovel(imovel):
janela_detalhes = tk.Toplevel()
janela_detalhes.title(f"Detalhes do Imóvel {imovel.codigo} - {imovel.tipo()}")
janela_detalhes.geometry("400x600")
janela_detalhes.protocol("WM_DELETE_WINDOW", lambda: fechar_e_reabrir_menu(janela_detalhes, root))
quartos_var = tk.IntVar(value=1)
camas_var = tk.IntVar(value=1)
casal_var = tk.BooleanVar(value=False)
cozinha_var = tk.BooleanVar(value=False)
escritorio_var = tk.BooleanVar(value=False)
andar_var = tk.IntVar(value=0 if imovel.tipo() != "Apartamento" else 1)
objetos_var = tk.StringVar(value="")
extra_vars = {}
def salvar_detalhes():
try:
quartos = int(quartos_var.get())
except (tk.TclError, ValueError):
quartos = 0
try:
camas = int(camas_var.get())
except (tk.TclError, ValueError):
camas = 0
try:
andar = int(andar_var.get()) if imovel.tipo() == "Apartamento" else None
except (tk.TclError, ValueError):
andar = None
objetos = [obj.strip() for obj in objetos_var.get().split(",") if obj.strip()]
detalhes_imoveis[imovel.codigo] = {
"quartos": quartos,
"camas": camas,
"cama_de_casal": casal_var.get(),
"cozinha": cozinha_var.get(),
"escritorio": escritorio_var.get(),
"andar": andar,
"objetos": objetos
}
detalhes_extras = {}
for chave, var in extra_vars.items():
try:
detalhes_extras[chave] = var.get()
except (tk.TclError, ValueError):
if isinstance(var, tk.IntVar):
detalhes_extras[chave] = 0
elif isinstance(var, tk.DoubleVar):
detalhes_extras[chave] = 0.0
elif isinstance(var, tk.BooleanVar):
detalhes_extras[chave] = False
else:
detalhes_extras[chave] = ""
imovel.set_detalhes_extras(detalhes_extras)
messagebox.showinfo("Sucesso", "Detalhes do imóvel foram salvos.")
janela_detalhes.destroy()
root.deiconify()
tk.Label(janela_detalhes, text="Quartos:").pack(pady=5)
tk.Spinbox(janela_detalhes, from_=0, to=20, textvariable=quartos_var, width=3).pack()
tk.Label(janela_detalhes, text="Quantidade de camas:").pack(pady=5)
tk.Spinbox(janela_detalhes, from_=0, to=20, textvariable=camas_var, width=3).pack()
tk.Checkbutton(janela_detalhes, text="Cama de Casal", variable=casal_var).pack(pady=5)
tk.Checkbutton(janela_detalhes, text="Cozinha", variable=cozinha_var).pack(pady=5)
tk.Checkbutton(janela_detalhes, text="Escritório", variable=escritorio_var).pack(pady=5)
if imovel.tipo() == "Apartamento":
tk.Label(janela_detalhes, text="Andar:").pack(pady=5)
tk.Spinbox(janela_detalhes, from_=0, to=50, textvariable=andar_var).pack()
tipo = imovel.tipo()
if tipo in ["Casa", "Casa Geminada", "Sobrado"]:
extra_vars["quintal"] = tk.BooleanVar(value=getattr(imovel, "quintal", False))
extra_vars["garagem"] = tk.BooleanVar(value=getattr(imovel, "garagem", False))
extra_vars["área_de_serviço_externo"] = tk.BooleanVar(value=getattr(imovel, "área_de_serviço_externo", False))
extra_vars["tem_edicula"] = tk.BooleanVar(value=getattr(imovel, "tem_edicula", False))
tk.Checkbutton(janela_detalhes, text="Quintal", variable=extra_vars["quintal"]).pack(pady=5)
tk.Checkbutton(janela_detalhes, text="Garagem", variable=extra_vars["garagem"]).pack(pady=5)
tk.Checkbutton(janela_detalhes, text="Área de Serviço Externo", variable=extra_vars["área_de_serviço_externo"]).pack(pady=5)
tk.Checkbutton(janela_detalhes, text="Possui Edícula", variable=extra_vars["tem_edicula"]).pack(pady=5)
elif tipo == "Edícula":
extra_vars["area_construida"] = tk.DoubleVar(value=getattr(imovel, "area_construida", 0.0))
extra_vars["independente"] = tk.BooleanVar(value=getattr(imovel, "independente", False))
extra_vars["banheiro_proprio"] = tk.BooleanVar(value=getattr(imovel, "banheiro_proprio", False))
tk.Label(janela_detalhes, text="Área Construída (m²):").pack(pady=5)
tk.Spinbox(janela_detalhes, from_=0, to=1000, increment=0.1, textvariable=extra_vars["area_construida"]).pack()
tk.Checkbutton(janela_detalhes, text="Independente", variable=extra_vars["independente"]).pack(pady=5)
tk.Checkbutton(janela_detalhes, text="Banheiro Próprio", variable=extra_vars["banheiro_proprio"]).pack(pady=5)
elif tipo in ["Kitnet/Studio", "Loft"]:
extra_vars["area_total"] = tk.DoubleVar(value=0.0)
extra_vars["cozinha_integrada"] = tk.BooleanVar(value=False)
extra_vars["area_servico"] = tk.BooleanVar(value=False)
extra_vars["mobilhado"] = tk.BooleanVar(value=False)
tk.Label(janela_detalhes, text="Área Total (m²):").pack(pady=5)
tk.Spinbox(janela_detalhes, from_=0, to=300, increment=0.1, textvariable=extra_vars["area_total"]).pack()
tk.Checkbutton(janela_detalhes, text="Cozinha Integrada", variable=extra_vars["cozinha_integrada"]).pack(pady=5)
tk.Checkbutton(janela_detalhes, text="Área de Serviço", variable=extra_vars["area_servico"]).pack(pady=5)
tk.Checkbutton(janela_detalhes, text="Mobiliado", variable=extra_vars["mobilhado"]).pack(pady=5)
tk.Label(janela_detalhes, text="Objetos dentro da casa (separados por vírgula):").pack(pady=5)
tk.Entry(janela_detalhes, textvariable=objetos_var, width=40).pack()
tk.Button(janela_detalhes, text="Salvar Detalhes", command=salvar_detalhes).pack(pady=15)
def editar_imovel(imovel):
janela = tk.Toplevel()
janela.title(f"Editar Imóvel {imovel.codigo}")
janela.geometry("400x500")
janela.protocol("WM_DELETE_WINDOW", janela.destroy)
def salvar():
logradouro = entry_logradouro.get().strip()
bairro = entry_bairro.get().strip()
cidade = entry_cidade.get().strip()
estado = entry_estado.get().strip()
valor = entry_valor.get().strip()
if not logradouro or not bairro or not cidade or not estado or not valor:
messagebox.showwarning("Erro", "Todos os campos devem ser preenchidos.")
return
try:
valor_float = float(valor.replace('.', '').replace(',', '.'))
except ValueError:
messagebox.showerror("Erro", "Valor deve ser um número válido.")
return
endereco_completo = f"{logradouro} - {bairro} - {cidade}/{estado}"
imovel._Imovel__endereco = endereco_completo
imovel._Imovel__valor = valor_float
messagebox.showinfo("Sucesso", "Informações atualizadas com sucesso.")
janela.destroy()
root.deiconify()
logradouro, bairro, cidade_estado = imovel.endereco.split(" - ")
cidade, estado = cidade_estado.split("/")
tk.Label(janela, text="Rua:").pack()
entry_logradouro = tk.Entry(janela)
entry_logradouro.insert(0, logradouro)
entry_logradouro.pack()
tk.Label(janela, text="Bairro:").pack()
entry_bairro = tk.Entry(janela)
entry_bairro.insert(0, bairro)
entry_bairro.pack()
tk.Label(janela, text="Cidade:").pack()
entry_cidade = tk.Entry(janela)
entry_cidade.insert(0, cidade)
entry_cidade.pack()
tk.Label(janela, text="Estado:").pack()
entry_estado = tk.Entry(janela)
entry_estado.insert(0, estado)
entry_estado.pack()
tk.Label(janela, text="Valor da Locação:").pack()
entry_valor = tk.Entry(janela)
entry_valor.insert(0, f"{imovel.valor:.2f}".replace(".", ","))
entry_valor.pack()
tk.Button(janela, text="Editar Detalhes Extras", command=lambda: abrir_detalhes_imovel(imovel)).pack(pady=10)
tk.Button(janela, text="Salvar Alterações", command=salvar).pack(pady=15)
def mostrar_detalhes(imovel):
janela_detalhes = tk.Toplevel()
janela_detalhes.title(f"Detalhes do Imóvel {imovel.codigo} - {imovel.tipo()}")
janela_detalhes.geometry("450x450")
janela_detalhes.protocol("WM_DELETE_WINDOW", lambda: janela_detalhes.destroy())
detalhes = detalhes_imoveis.get(imovel.codigo, {})
extras = imovel.detalhes_extras()
texto = f"""
Código: {imovel.codigo}
Endereço: {imovel.endereco}
Valor: R${imovel.valor:.2f}
Tipo: {imovel.tipo()}
Status: {"Disponível" if imovel.disponivel else "Indisponível"}
Quartos: {detalhes.get('quartos', 'N/A')}
Camas: {detalhes.get('camas', 'N/A')}
Cama de Casal: {"Sim" if detalhes.get('cama_de_casal') else "Não"}
Cozinha: {"Sim" if detalhes.get('cozinha') else "Não"}
Escritório: {"Sim" if detalhes.get('escritorio') else "Não"}
"""
if imovel.tipo() == "Apartamento":
texto += f"Andar: {detalhes.get('andar', 'N/A')}\n"
objetos = detalhes.get('objetos', [])
if objetos:
texto += f"Objetos: {', '.join(objetos)}\n"
for chave, valor in extras.items():
if isinstance(valor, bool):
texto += f"{chave.replace('_', ' ').capitalize()}: {'Sim' if valor else 'Não'}\n"
else:
texto += f"{chave.replace('_', ' ').capitalize()}: {valor}\n"
label = tk.Label(janela_detalhes, text=texto, justify="left", anchor="w")
label.pack(padx=10, pady=10, fill='both')
def listar_imoveis():
root.withdraw()
janela = tk.Toplevel()
janela.title("Imóveis Disponíveis para Locação")
janela.geometry("900x400")
janela.protocol("WM_DELETE_WINDOW", lambda: fechar_e_reabrir_menu(janela, root))
disponiveis = [i for i in imoveis if i.disponivel]
if not disponiveis:
tk.Label(janela, text="Nenhum imóvel disponível para locação.").pack(pady=20)
return
for imovel in disponiveis:
frame = tk.Frame(janela, borderwidth=1, relief="solid", padx=5, pady=5)
frame.pack(fill='x', padx=10, pady=5)
valor_formatado = f"R$ {imovel.valor:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".")
texto = (f"Código: {imovel.codigo} | Endereço: {imovel.endereco} | "
f"Valor: {valor_formatado} | Tipo: {imovel.tipo()} | Status: Disponível")
label = tk.Label(frame, text=texto, anchor="w", justify="left")
label.pack(side='top', fill='x')
botoes_frame = tk.Frame(frame)
botoes_frame.pack(pady=5)
tk.Button(botoes_frame, text="Detalhes", command=lambda i=imovel: mostrar_detalhes(i)).pack(side="left", padx=5)
tk.Button(botoes_frame, text="Editar", command=lambda i=imovel: editar_imovel(i)).pack(side="left", padx=5)
def cadastrar_cliente():
root.withdraw()
janela = tk.Toplevel()
janela.title("Cadastrar Cliente")
janela.geometry("350x450")
janela.protocol("WM_DELETE_WINDOW", lambda: fechar_e_reabrir_menu(janela, root))
cpf_var = tk.StringVar()
nome_var = tk.StringVar()
data_nasc_var = tk.StringVar()
telefone_var = tk.StringVar()
email_var = tk.StringVar()
estado_civil_var = tk.StringVar()
endereco_var = tk.StringVar()
profissao_var = tk.StringVar()
renda_var = tk.StringVar()
def salvar():
cpf = cpf_var.get().strip()
nome = nome_var.get().strip()
data_nasc = data_nasc_var.get().strip()
telefone = telefone_var.get().strip()
email = email_var.get().strip()
estado_civil = estado_civil_var.get()
endereco = endereco_var.get().strip()
profissao = profissao_var.get().strip()
renda = renda_var.get().strip()
cpf_numeros = ''.join(filter(str.isdigit, cpf))
if len(cpf_numeros) != 11:
messagebox.showerror("Erro", "CPF inválido. Deve conter 11 números.")
return
if not nome:
messagebox.showwarning("Erro", "Preencha o nome.")
return
if any(c.cpf == cpf_numeros for c in clientes):
messagebox.showerror("Erro", "CPF já cadastrado.")
return
cliente = Cliente(
cpf_numeros, nome, data_nasc, telefone, email,
estado_civil, endereco, profissao, renda
)
clientes.append(cliente)
messagebox.showinfo("Sucesso", "Cliente cadastrado com sucesso.")
janela.destroy()
root.deiconify()
def formatar_cpf(event):
texto = cpf_var.get()
numeros = ''.join(filter(str.isdigit, texto))
novo = ''
for i, n in enumerate(numeros):
if i == 3 or i == 6:
novo += '.'
elif i == 9:
novo += '-'
novo += n
if i >= 10:
break
pos = entry_cpf.index(tk.INSERT)
cpf_var.set(novo)
novo_pos = pos
if pos in [3, 7, 11]:
novo_pos += 1
if novo_pos > len(novo):
novo_pos = len(novo)
entry_cpf.icursor(novo_pos)
def formatar_data_nascimento(event):
texto = data_nasc_var.get()
numeros = ''.join(filter(str.isdigit, texto))
novo = ''
for i, n in enumerate(numeros):
if i == 2 or i == 4:
novo += '/'
novo += n
if i >= 7:
break
pos = entry_data_nasc.index(tk.INSERT)
data_nasc_var.set(novo)
novo_pos = pos
if pos in [2, 5]:
novo_pos += 1
if novo_pos > len(novo):
novo_pos = len(novo)
entry_data_nasc.icursor(novo_pos)
def formatar_telefone(event):
texto = telefone_var.get()
numeros = ''.join(filter(str.isdigit, texto))
novo = ''
for i, n in enumerate(numeros):
if i == 0:
novo += '('
elif i == 2:
novo += ') '
elif i == 7:
novo += '-'
novo += n
if i >= 10:
break
telefone_var.set(novo)
tk.Label(janela, text="CPF:").pack(pady=2)
entry_cpf = tk.Entry(janela, textvariable=cpf_var, justify='center')
entry_cpf.pack()
entry_cpf.bind('<KeyRelease>', formatar_cpf)
tk.Label(janela, text="Nome:").pack(pady=2)
tk.Entry(janela, textvariable=nome_var, justify='center').pack()
tk.Label(janela, text="Data de Nascimento:").pack(pady=2)
entry_data_nasc = tk.Entry(janela, textvariable=data_nasc_var, justify='center')
entry_data_nasc.pack()
entry_data_nasc.bind('<KeyRelease>', formatar_data_nascimento)
tk.Label(janela, text="Telefone:").pack(pady=2)
entry_telefone = tk.Entry(janela, textvariable=telefone_var, justify='center')
entry_telefone.pack()
entry_telefone.bind('<KeyRelease>', formatar_telefone)
tk.Label(janela, text="Email:").pack(pady=2)
tk.Entry(janela, textvariable=email_var, justify='center').pack()
tk.Label(janela, text="Endereço:").pack(pady=2)
tk.Entry(janela, textvariable=endereco_var, justify='center').pack()
tk.Label(janela, text="Profissão:").pack(pady=2)
tk.Entry(janela, textvariable=profissao_var, justify='center').pack()
tk.Label(janela, text="Renda Mensal:").pack(pady=2)
tk.Entry(janela, textvariable=renda_var, justify='center').pack()
tk.Button(janela, text="Salvar", command=salvar).pack(pady=10)
def realizar_locacao():
root.withdraw()
janela = tk.Toplevel()
janela.title("Realizar Locação")
janela.geometry("300x200")
janela.resizable(False, False)
janela.protocol("WM_DELETE_WINDOW", lambda: fechar_e_reabrir_menu(janela, root))
frame = tk.Frame(janela)
frame.pack(expand=True)
def formatar_cpf(event):
texto = entry_cpf.get()
numeros = ''.join(filter(str.isdigit, texto))
novo = ''
for i, n in enumerate(numeros):
if i == 3 or i == 6:
novo += '.'
elif i == 9:
novo += '-'
novo += n
if i >= 10:
break
entry_cpf.delete(0, tk.END)
entry_cpf.insert(0, novo)
def alugar():
cpf = ''.join(filter(str.isdigit, entry_cpf.get()))
codigo = entry_codigo.get().strip()
cliente = next((c for c in clientes if c.cpf == cpf), None)
imovel = next((i for i in imoveis if i.codigo == codigo and i.disponivel), None)
if not cliente:
messagebox.showerror("Erro", "Cliente não encontrado.")
return
if not imovel:
messagebox.showerror("Erro", "Imóvel não encontrado ou indisponível.")
return
imovel.disponivel = False
locacoes.append({"cliente": cliente, "imovel": imovel})
messagebox.showinfo("Sucesso", "Parabéns! Você realizou sua locação com sucesso!")
janela.destroy()
root.deiconify()
tk.Label(frame, text="CPF do Cliente:").pack(pady=(5, 0))
entry_cpf = tk.Entry(frame, justify="center")
entry_cpf.pack(pady=(0, 10))
entry_cpf.bind('<KeyRelease>', formatar_cpf)
tk.Label(frame, text="Código do Imóvel:").pack(pady=(5, 0))
entry_codigo = tk.Entry(frame, justify="center")
entry_codigo.pack(pady=(0, 10))
tk.Button(frame, text="Alugar", command=alugar).pack(pady=(10, 5))
def listar_locacoes():
root.withdraw()
janela = tk.Toplevel()
janela.title("Locações Realizadas")
janela.geometry("600x400")
janela.protocol("WM_DELETE_WINDOW", lambda: fechar_e_reabrir_menu(janela, root))
if not locacoes:
tk.Label(janela, text="Nenhuma locação realizada.").pack()
return
for loc in locacoes:
cliente_nome = loc['cliente'].nome
imovel = loc['imovel']
endereco = imovel.endereco
tipo = imovel.tipo()
valor_formatado = f"R$ {imovel.valor:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".")
texto = f"{cliente_nome} alugou uma {tipo} na {endereco} por {valor_formatado}"
tk.Label(janela, text=texto, anchor="w", justify="left").pack(fill='x', padx=10, pady=2)
root = tk.Tk()
root.title("Sistema de Locação de Imóveis")
root.geometry("500x400")
root.minsize(400, 300)
def fechar_e_reabrir_menu(janela_atual, janela_anterior=root):
janela_atual.destroy()
janela_anterior.deiconify()
frame_menu = tk.Frame(root)
frame_menu.pack(fill="both", expand=True, padx=20, pady=10)
tk.Label(frame_menu, text="Menu Principal", font=("Arial", 30)).grid(row=0, column=0, columnspan=2, pady=(0, 20))
for i in range(5):
frame_menu.grid_rowconfigure(i, weight=1)
for j in range(2):
frame_menu.grid_columnconfigure(j, weight=1)
botoes = [
("Cadastrar Imóvel", cadastrar_imovel),
("Listar Imóveis", listar_imoveis),
("Cadastrar Cliente", cadastrar_cliente),
("Realizar Locação", realizar_locacao),
("Listar Locações", listar_locacoes),
("Remover Imóvel", remover_imovel),
("Sair", root.quit),
]
for idx, (texto, comando) in enumerate(botoes):
if texto == "Sair":
btn = tk.Button(frame_menu, text=texto, command=comando, font=("Arial", 12), height=2)
btn.grid(row=(idx // 2) + 1, column=0, columnspan=2, padx=10, pady=10, sticky="ew")
else:
row = (idx // 2) + 1
col = idx % 2
btn = tk.Button(frame_menu, text=texto, command=comando, font=("Arial", 12), height=2)
btn.grid(row=row, column=col, padx=10, pady=10, sticky="nsew")
root.mainloop()