Saludos. Alguien puede corregir el código de tal manera que luego de eliminar un registro éste cambio sea permanente??? Luego de eliminar y abrir la BD el registro reaparece.
No hay manera de lograrlo. ME dicen que por el ID pero modifico para que lo muestre y me desajusta lo demás como guardar un nuevo registro.
import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3
import re
from datetime import datetime, timedelta
def conectar_db():
conexion = sqlite3.connect('mi_base_de_datos3.db')
cursor = conexion.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS registros (
ID INTEGER PRIMARY KEY AUTOINCREMENT,
REG INT,
GBT INT,
CMF INT,
HOGAR TEXT,
CPAT_DPAT TEXT,
CI TEXT,
NOMBRE TEXT,
APELLIDO1 TEXT,
APELLIDO2 TEXT,
EDAD INTEGER,
CALLE TEXT,
No_KM TEXT,
BARRIO_O_REPARTO TEXT,
USD TEXT,
FUM_FUSD DATE,
FPP DATE,
SEM INTEGER,
DIAS INTEGER,
EG TEXT,
Trim TEXT,
CLASIF TEXT,
FACTORES_DE_RIESGO TEXT,
OBSERVACIONES TEXT
)
''')
conexion.commit()
conexion.close()
def calcular_edad(fecha_nacimiento):
fecha_actual = datetime.now()
edad = fecha_actual.year - fecha_nacimiento.year - ((fecha_actual.month, fecha_actual.day) < (fecha_nacimiento.month, fecha_nacimiento.day))
return edad
class Aplicacion:
def __init__(self, root):
self.root = root
self.root.title("Gestión de Base de Datos")
self.root.state('zoomed')
conectar_db()
# Configuración de estilos para el Treeview
style = ttk.Style(root)
style.configure("RET.Treeview", background="light blue", foreground="black")
style.configure("PRO.Treeview", background="light blue", foreground="black")
style.configure("HOS.Treeview", background="yellow", foreground="black")
style.configure("NEC.Treeview", background="light green", foreground="black")
style.configure("PRE.Treeview", background="light grey", foreground="black")
self.campos = ['REG', 'GBT', 'CMF', 'HOGAR', 'CPAT_DPAT', 'CI', 'NOMBRE', 'APELLIDO1', 'APELLIDO2', 'EDAD', 'CALLE', 'No_KM', 'BARRIO_O_REPARTO', 'USD', 'FUM_FUSD', 'FPP', 'SEM', 'DIAS', 'EG', 'Trim', 'CLASIF', 'FACTORES_DE_RIESGO', 'OBSERVACIONES']
self.entries = {}
frame_inputs = tk.Frame(root)
frame_inputs.grid(row=0, column=0, sticky="nsew")
for i, campo in enumerate(self.campos):
label = tk.Label(frame_inputs, text=campo)
entry = tk.Entry(frame_inputs, width=17, justify=tk.CENTER) # Ajusta el ancho según sea necesario
if i < len(self.campos) / 2: # Posicionar en la primera fila
label.grid(column=i, row=0, padx=5, pady=5)
entry.grid(column=i, row=1, padx=5, pady=5)
else: # Posicionar en la segunda fila
label.grid(column=i - len(self.campos) // 2, row=2, padx=5, pady=5)
entry.grid(column=i - len(self.campos) // 2, row=3, padx=5, pady=5)
self.entries[campo] = entry
# Crear el Label para el Entry de filtrado por CMF
label_filtrar_cmf = tk.Label(frame_inputs, text="Filtrar CMF", font=('Arial', 8, 'bold'))
label_filtrar_cmf.grid(row=3, column=0, padx=5, pady=5, sticky='w')
# Crear el Entry para filtrar por CMF
self.entry_filtrar_cmf = tk.Entry(frame_inputs, width=5)
self.entry_filtrar_cmf.grid(row=4, column=0, padx=5, pady=5)
self.entry_filtrar_cmf.bind("<KeyRelease>", self.filtrar_por_cmf)
self.boton_ordenar_hogar = tk.Button(frame_inputs, text="Ordenar por HOGAR", command=self.ordenar_por_hogar)
self.boton_ordenar_hogar.grid(row=len(self.campos) + 1, column=2, pady=10)
self.boton_ordenar_gbt = tk.Button(frame_inputs, text="Ordenar por GBT", command=self.ordenar_por_gbt)
self.boton_ordenar_gbt.grid(row=len(self.campos) + 1, column=3, pady=10)
self.boton_ordenar_cmf = tk.Button(frame_inputs, text="Ordenar por CMF", command=self.ordenar_por_cmf)
self.boton_ordenar_cmf.grid(row=len(self.campos) + 1, column=4, pady=10)
self.boton_agregar = tk.Button(frame_inputs, text="Agregar Registro", command=self.agregar_registro)
self.boton_visualizar = tk.Button(frame_inputs, text="Visualizar Registros", command=self.visualizar_registros)
self.boton_eliminar = tk.Button(frame_inputs, text="Eliminar Registro", command=self.eliminar_registro)
self.boton_agregar.grid(row=len(self.campos)+1, column=0, pady=10)
self.boton_visualizar.grid(row=len(self.campos)+1, column=11, pady=10)
self.boton_eliminar.grid(row=len(self.campos)+1, column=1, pady=10)
#....................................................................................
frame_table = tk.Frame(root)
frame_table.grid(row=1, column=0, sticky="nsew")
self.tabla = ttk.Treeview(frame_table, columns=self.campos, show="headings")
for campo in self.campos:
self.tabla.heading(campo, text=campo)
self.tabla.column(campo, width=60, minwidth=50)
self.tabla.grid(row=0, column=0, sticky="nsew")
frame_table.grid_rowconfigure(0, weight=1)
frame_table.grid_columnconfigure(0, weight=1)
root.rowconfigure(1, weight=1)
#....................................................................................
self.entries['CI'].bind("<KeyRelease>", self.calcular_edad_evento)
self.entries['CI'].bind("<FocusOut>", self.validar_ci_evento)
self.entries['FUM_FUSD'].bind("<FocusOut>", self.validar_fecha_fum_fusd)
self.entries['FUM_FUSD'].bind("<KeyRelease>", self.actualizar_datos_gestacionales)
self.entries['DIAS'].bind("<KeyRelease>", self.validar_dias)
self.entries['SEM'].bind("<KeyRelease>", self.actualizar_datos_gestacionales)
self.visualizar_registros()
self.ordenar_por_cmf()
#....................................................................................
def agregar_registro(self):
if not self.validar_campos() or not self.validar_factores_de_riesgo():
return
self.actualizar_datos_gestacionales() # Asegurarse de que FPP, EG y Trim estén actualizados
valores = {campo: self.entries[campo].get() for campo in self.entries}
with sqlite3.connect('mi_base_de_datos3.db') as conexion:
cursor = conexion.cursor()
campos = ', '.join(valores.keys())
placeholders = ', '.join(['?']*len(valores))
sql = f'INSERT INTO registros ({campos}) VALUES ({placeholders})'
cursor.execute(sql, list(valores.values()))
conexion.commit()
self.visualizar_registros()
#....................................................................................
def eliminar_registro(self):
selected_item = self.tabla.selection()
if not selected_item:
messagebox.showinfo("Error", "No hay ningún registro seleccionado")
return
id = self.tabla.item(selected_item[0])['values'][0]
try:
with sqlite3.connect('mi_base_de_datos3.db') as conexion:
cursor = conexion.cursor()
cursor.execute('DELETE FROM registros WHERE ID=?', (id,))
conexion.commit()
self.tabla.delete(selected_item[0])
except Exception as e:
messagebox.showerror("Error", f"No se pudo eliminar el registro: {str(e)}")
#....................................................................................
def filtrar_por_cmf(self, event=None):
valor_filtro = self.entry_filtrar_cmf.get().strip()
if valor_filtro:
try:
valor_filtro = int(valor_filtro)
# Obtener los registros filtrados por CMF
with sqlite3.connect('mi_base_de_datos3.db') as conexion:
cursor = conexion.cursor()
cursor.execute("SELECT * FROM registros WHERE CMF=?", (valor_filtro,))
rows = cursor.fetchall()
self.actualizar_vista_treeview(rows)
except ValueError:
messagebox.showerror("Error", "El valor para filtrar por CMF debe ser un número entero")
else:
# Si el Entry está vacío, mostrar todos los registros
self.visualizar_registros()
#....................................................................................
def ordenar_por_hogar(self):
# Obtener los datos y ordenarlos
with sqlite3.connect('mi_base_de_datos3.db') as conexion:
cursor = conexion.cursor()
cursor.execute("SELECT * FROM registros ORDER BY HOGAR")
rows = cursor.fetchall()
self.actualizar_vista_treeview(rows)
#....................................................................................
def ordenar_por_gbt(self):
# Obtener los datos y ordenarlos
with sqlite3.connect('mi_base_de_datos3.db') as conexion:
cursor = conexion.cursor()
cursor.execute("SELECT * FROM registros ORDER BY GBT")
rows = cursor.fetchall()
self.actualizar_vista_treeview(rows)
#....................................................................................
def ordenar_por_cmf(self):
# Obtener los datos y ordenarlos
with sqlite3.connect('mi_base_de_datos3.db') as conexion:
cursor = conexion.cursor()
cursor.execute("SELECT * FROM registros ORDER BY CMF")
rows = cursor.fetchall()
self.actualizar_vista_treeview(rows)
#....................................................................................
def actualizar_vista_treeview(self, rows):
# Limpiar el Treeview antes de rellenarlo
for i in self.tabla.get_children():
self.tabla.delete(i)
# Insertar los nuevos datos ordenados
for row in rows:
estilo = ''
if row[4] == 'RET': # Suponiendo que 'HOGAR' es el quinto elemento en la fila
estilo = 'RET.Treeview'
elif row[4] == 'PRO':
estilo = 'PRO.Treeview'
elif row[4] == 'HOS':
estilo = 'HOS.Treeview'
elif row[4] == 'NEC':
estilo = 'NEC.Treeview'
elif row[4] == 'PRE':
estilo = 'PRE.Treeview'
self.tabla.insert('', 'end', values=row[1:], tags=estilo)
if estilo:
self.tabla.tag_configure(estilo, background=('light blue' if row[4] == 'RET' else
'yellow' if row[4] == 'HOS' else
'light green' if row[4] == 'NEC' else
'light grey' if row[4] == 'PRE' else
'light blue' if row[4] == 'PRO' else
'black'))
#....................................................................................
def actualizar_datos_gestacionales(self, event=None):
if self.validar_fecha(self.entries['FUM_FUSD'].get().strip()):
self.actualizar_fpp()
self.actualizar_eg()
# New: Calculate and update trimester based on EG
eg = float(self.entries['EG'].get().strip() or 0)
self.calcular_trim(eg)
#....................................................................................
def actualizar_fpp(self):
fpp = self.calcular_fpp()
if fpp:
self.entries['FPP'].delete(0, tk.END)
self.entries['FPP'].insert(0, fpp)
#....................................................................................
def actualizar_eg(self):
fecha_fum_fusd = self.entries['FUM_FUSD'].get().strip()
dias_adicionales = int(self.entries['DIAS'].get().strip() or 0)
semanas_adicionales = int(self.entries['SEM'].get().strip() or 0) * 7
if self.validar_fecha(fecha_fum_fusd):
fecha_fum_fusd = datetime.strptime(fecha_fum_fusd, "%Y-%m-%d")
total_dias = (datetime.now() - fecha_fum_fusd).days + dias_adicionales + semanas_adicionales
semanas = total_dias // 7
dias = total_dias % 7
self.entries['EG'].delete(0, tk.END)
self.entries['EG'].insert(0, f"{semanas}.{dias}")
self.calcular_trim(semanas + dias / 7) # Update Trim based on the new EG
#....................................................................................
def calcular_edad_evento(self, event):
ci = self.entries['CI'].get().strip()
if len(ci) >= 6:
try:
fecha_nacimiento = datetime.strptime(ci[:6], "%y%m%d")
edad = calcular_edad(fecha_nacimiento)
self.entries['EDAD'].delete(0, tk.END)
self.entries['EDAD'].insert(0, str(edad))
except ValueError:
pass
#....................................................................................
def calcular_fpp(self):
try:
fecha_fum_fusd = datetime.strptime(self.entries['FUM_FUSD'].get(), "%Y-%m-%d")
dias = int(self.entries['DIAS'].get() or 0)
sem = int(self.entries['SEM'].get() or 0)
fpp = fecha_fum_fusd + timedelta(days=280 - (dias + sem*7))
return fpp.strftime("%Y-%m-%d")
except ValueError:
return ""
#....................................................................................
def calcular_trim(self, eg):
"""Calculates and updates the trimester based on gestational age."""
if eg <= 12.6:
trim = 'I'
elif 13 <= eg <= 22.6:
trim = 'II'
elif eg >= 23:
trim = 'III'
else:
trim = '' # In case of an out-of-range or invalid EG value
self.entries['Trim'].delete(0, tk.END)
self.entries['Trim'].insert(0, trim)
#....................................................................................
def visualizar_registros(self):
for i in self.tabla.get_children():
self.tabla.delete(i)
with sqlite3.connect('mi_base_de_datos3.db') as conexion:
cursor = conexion.cursor()
cursor.execute("SELECT * FROM registros")
rows = cursor.fetchall()
for row in rows:
estilo = ''
if row[4] == 'RET': # Suponiendo que 'HOGAR' es el quinto elemento en la fila
estilo = 'RET.Treeview'
elif row[4] == 'PRO':
estilo = 'PRO.Treeview'
elif row[4] == 'HOS':
estilo = 'HOS.Treeview'
elif row[4] == 'NEC':
estilo = 'NEC.Treeview'
elif row[4] == 'PRE':
estilo = 'PRE.Treeview'
self.tabla.insert('', 'end', values=row[1:], tags=estilo)
if estilo:
self.tabla.tag_configure(estilo, background=('light blue' if row[4] == 'RET' else
'yellow' if row[4] == 'HOS' else
'light green' if row[4] == 'NEC' else
'light grey' if row[4] == 'PRE' else
'light blue' if row[4] == 'PRO' else
'black'))
#....................................................................................
def validar_ci_evento(self, event):
ci = self.entries['CI'].get().strip()
if not self.validar_ci(ci):
messagebox.showerror("Error de Validación", "El campo CI debe tener exactamente 11 dígitos y el penúltimo debe ser impar")
self.entries['CI'].delete(0, tk.END)
self.entries['CI'].focus_set()
#....................................................................................
def validar_ci(self, ci):
if len(ci) == 11 and ci.isdigit():
penultimo_digito = int(ci[-2])
return penultimo_digito % 2 != 0
return False
#....................................................................................
def validar_dias(self, event=None):
dias = self.entries['DIAS'].get().strip()
if dias: # Si hay algún valor, verifica que sea adecuado
if not dias.isdigit() or not (1 <= int(dias) <= 6):
messagebox.showerror("Error de Validación", "El campo DIAS debe estar en blanco o ser un número entre 1 y 6")
self.entries['DIAS'].delete(0, tk.END) # Borra el contenido incorrecto
self.entries['DIAS'].focus_set() # Devuelve el enfoque al campo DIAS
else:
# Si el valor es válido, actualizamos datos gestacionales.
self.actualizar_datos_gestacionales()
else:
# También actualizar si el campo se deja en blanco, lo que puede cambiar los cálculos.
self.actualizar_datos_gestacionales()
#....................................................................................
def validar_factores_de_riesgo(self):
clasif = self.entries['CLASIF'].get().strip()
factores_de_riesgo = self.entries['FACTORES_DE_RIESGO'].get().strip()
if clasif == 'Normal' and factores_de_riesgo:
messagebox.showerror("Error de Validación", "Si CLASIF es 'Normal', el campo FACTORES_DE_RIESGO debe estar vacío.")
self.entries['FACTORES_DE_RIESGO'].focus_set()
return False
elif clasif in ['ARO', 'BRO', 'CAV'] and not factores_de_riesgo:
messagebox.showerror("Error de Validación", "Si CLASIF es 'ARO', 'BRO' o 'CAV', el campo FACTORES_DE_RIESGO no puede estar vacío.")
self.entries['FACTORES_DE_RIESGO'].focus_set()
return False
return True
#....................................................................................
def validar_fecha_fum_fusd(self, event):
fecha = self.entries['FUM_FUSD'].get().strip()
if fecha:
if not self.validar_fecha(fecha):
messagebox.showerror("Error", "El campo FUM_FUSD debe tener el formato YYYY-MM-DD")
self.entries['FUM_FUSD'].delete(0, tk.END)
self.entries['FUM_FUSD'].focus_set()
#....................................................................................
def validar_fecha(self, fecha):
patron = r'\d{4}-\d{2}-\d{2}'
return re.match(patron, fecha)
#....................................................................................
def validar_clasif(self, clasif):
permitidos = ['Normal', 'ARO', 'BRO', 'CAV']
return clasif in permitidos
#....................................................................................
def validar_campos(self):
campos_obligatorios = ['GBT', 'CMF', 'CI', 'NOMBRE', 'APELLIDO1', 'APELLIDO2', 'CALLE', 'No_KM', 'BARRIO_O_REPARTO', 'FUM_FUSD', 'CLASIF']
for campo in campos_obligatorios:
if not self.entries[campo].get().strip():
messagebox.showerror("Error", f"El campo {campo} no puede estar vacío")
self.entries[campo].focus_set()
return False
if campo == 'CLASIF' and not self.validar_clasif(self.entries['CLASIF'].get().strip()):
messagebox.showerror("Error de Validación", "El campo CLASIF debe ser uno de los siguientes: Normal, ARO, BRO, CAV")
self.entries['CLASIF'].delete(0, tk.END)
self.entries['CLASIF'].focus_set()
return False
return True
root = tk.Tk()
app = Aplicacion(root)
root.mainloop()
No hay manera de lograrlo. ME dicen que por el ID pero modifico para que lo muestre y me desajusta lo demás como guardar un nuevo registro.
import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3
import re
from datetime import datetime, timedelta
def conectar_db():
conexion = sqlite3.connect('mi_base_de_datos3.db')
cursor = conexion.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS registros (
ID INTEGER PRIMARY KEY AUTOINCREMENT,
REG INT,
GBT INT,
CMF INT,
HOGAR TEXT,
CPAT_DPAT TEXT,
CI TEXT,
NOMBRE TEXT,
APELLIDO1 TEXT,
APELLIDO2 TEXT,
EDAD INTEGER,
CALLE TEXT,
No_KM TEXT,
BARRIO_O_REPARTO TEXT,
USD TEXT,
FUM_FUSD DATE,
FPP DATE,
SEM INTEGER,
DIAS INTEGER,
EG TEXT,
Trim TEXT,
CLASIF TEXT,
FACTORES_DE_RIESGO TEXT,
OBSERVACIONES TEXT
)
''')
conexion.commit()
conexion.close()
def calcular_edad(fecha_nacimiento):
fecha_actual = datetime.now()
edad = fecha_actual.year - fecha_nacimiento.year - ((fecha_actual.month, fecha_actual.day) < (fecha_nacimiento.month, fecha_nacimiento.day))
return edad
class Aplicacion:
def __init__(self, root):
self.root = root
self.root.title("Gestión de Base de Datos")
self.root.state('zoomed')
conectar_db()
# Configuración de estilos para el Treeview
style = ttk.Style(root)
style.configure("RET.Treeview", background="light blue", foreground="black")
style.configure("PRO.Treeview", background="light blue", foreground="black")
style.configure("HOS.Treeview", background="yellow", foreground="black")
style.configure("NEC.Treeview", background="light green", foreground="black")
style.configure("PRE.Treeview", background="light grey", foreground="black")
self.campos = ['REG', 'GBT', 'CMF', 'HOGAR', 'CPAT_DPAT', 'CI', 'NOMBRE', 'APELLIDO1', 'APELLIDO2', 'EDAD', 'CALLE', 'No_KM', 'BARRIO_O_REPARTO', 'USD', 'FUM_FUSD', 'FPP', 'SEM', 'DIAS', 'EG', 'Trim', 'CLASIF', 'FACTORES_DE_RIESGO', 'OBSERVACIONES']
self.entries = {}
frame_inputs = tk.Frame(root)
frame_inputs.grid(row=0, column=0, sticky="nsew")
for i, campo in enumerate(self.campos):
label = tk.Label(frame_inputs, text=campo)
entry = tk.Entry(frame_inputs, width=17, justify=tk.CENTER) # Ajusta el ancho según sea necesario
if i < len(self.campos) / 2: # Posicionar en la primera fila
label.grid(column=i, row=0, padx=5, pady=5)
entry.grid(column=i, row=1, padx=5, pady=5)
else: # Posicionar en la segunda fila
label.grid(column=i - len(self.campos) // 2, row=2, padx=5, pady=5)
entry.grid(column=i - len(self.campos) // 2, row=3, padx=5, pady=5)
self.entries[campo] = entry
# Crear el Label para el Entry de filtrado por CMF
label_filtrar_cmf = tk.Label(frame_inputs, text="Filtrar CMF", font=('Arial', 8, 'bold'))
label_filtrar_cmf.grid(row=3, column=0, padx=5, pady=5, sticky='w')
# Crear el Entry para filtrar por CMF
self.entry_filtrar_cmf = tk.Entry(frame_inputs, width=5)
self.entry_filtrar_cmf.grid(row=4, column=0, padx=5, pady=5)
self.entry_filtrar_cmf.bind("<KeyRelease>", self.filtrar_por_cmf)
self.boton_ordenar_hogar = tk.Button(frame_inputs, text="Ordenar por HOGAR", command=self.ordenar_por_hogar)
self.boton_ordenar_hogar.grid(row=len(self.campos) + 1, column=2, pady=10)
self.boton_ordenar_gbt = tk.Button(frame_inputs, text="Ordenar por GBT", command=self.ordenar_por_gbt)
self.boton_ordenar_gbt.grid(row=len(self.campos) + 1, column=3, pady=10)
self.boton_ordenar_cmf = tk.Button(frame_inputs, text="Ordenar por CMF", command=self.ordenar_por_cmf)
self.boton_ordenar_cmf.grid(row=len(self.campos) + 1, column=4, pady=10)
self.boton_agregar = tk.Button(frame_inputs, text="Agregar Registro", command=self.agregar_registro)
self.boton_visualizar = tk.Button(frame_inputs, text="Visualizar Registros", command=self.visualizar_registros)
self.boton_eliminar = tk.Button(frame_inputs, text="Eliminar Registro", command=self.eliminar_registro)
self.boton_agregar.grid(row=len(self.campos)+1, column=0, pady=10)
self.boton_visualizar.grid(row=len(self.campos)+1, column=11, pady=10)
self.boton_eliminar.grid(row=len(self.campos)+1, column=1, pady=10)
#....................................................................................
frame_table = tk.Frame(root)
frame_table.grid(row=1, column=0, sticky="nsew")
self.tabla = ttk.Treeview(frame_table, columns=self.campos, show="headings")
for campo in self.campos:
self.tabla.heading(campo, text=campo)
self.tabla.column(campo, width=60, minwidth=50)
self.tabla.grid(row=0, column=0, sticky="nsew")
frame_table.grid_rowconfigure(0, weight=1)
frame_table.grid_columnconfigure(0, weight=1)
root.rowconfigure(1, weight=1)
#....................................................................................
self.entries['CI'].bind("<KeyRelease>", self.calcular_edad_evento)
self.entries['CI'].bind("<FocusOut>", self.validar_ci_evento)
self.entries['FUM_FUSD'].bind("<FocusOut>", self.validar_fecha_fum_fusd)
self.entries['FUM_FUSD'].bind("<KeyRelease>", self.actualizar_datos_gestacionales)
self.entries['DIAS'].bind("<KeyRelease>", self.validar_dias)
self.entries['SEM'].bind("<KeyRelease>", self.actualizar_datos_gestacionales)
self.visualizar_registros()
self.ordenar_por_cmf()
#....................................................................................
def agregar_registro(self):
if not self.validar_campos() or not self.validar_factores_de_riesgo():
return
self.actualizar_datos_gestacionales() # Asegurarse de que FPP, EG y Trim estén actualizados
valores = {campo: self.entries[campo].get() for campo in self.entries}
with sqlite3.connect('mi_base_de_datos3.db') as conexion:
cursor = conexion.cursor()
campos = ', '.join(valores.keys())
placeholders = ', '.join(['?']*len(valores))
sql = f'INSERT INTO registros ({campos}) VALUES ({placeholders})'
cursor.execute(sql, list(valores.values()))
conexion.commit()
self.visualizar_registros()
#....................................................................................
def eliminar_registro(self):
selected_item = self.tabla.selection()
if not selected_item:
messagebox.showinfo("Error", "No hay ningún registro seleccionado")
return
id = self.tabla.item(selected_item[0])['values'][0]
try:
with sqlite3.connect('mi_base_de_datos3.db') as conexion:
cursor = conexion.cursor()
cursor.execute('DELETE FROM registros WHERE ID=?', (id,))
conexion.commit()
self.tabla.delete(selected_item[0])
except Exception as e:
messagebox.showerror("Error", f"No se pudo eliminar el registro: {str(e)}")
#....................................................................................
def filtrar_por_cmf(self, event=None):
valor_filtro = self.entry_filtrar_cmf.get().strip()
if valor_filtro:
try:
valor_filtro = int(valor_filtro)
# Obtener los registros filtrados por CMF
with sqlite3.connect('mi_base_de_datos3.db') as conexion:
cursor = conexion.cursor()
cursor.execute("SELECT * FROM registros WHERE CMF=?", (valor_filtro,))
rows = cursor.fetchall()
self.actualizar_vista_treeview(rows)
except ValueError:
messagebox.showerror("Error", "El valor para filtrar por CMF debe ser un número entero")
else:
# Si el Entry está vacío, mostrar todos los registros
self.visualizar_registros()
#....................................................................................
def ordenar_por_hogar(self):
# Obtener los datos y ordenarlos
with sqlite3.connect('mi_base_de_datos3.db') as conexion:
cursor = conexion.cursor()
cursor.execute("SELECT * FROM registros ORDER BY HOGAR")
rows = cursor.fetchall()
self.actualizar_vista_treeview(rows)
#....................................................................................
def ordenar_por_gbt(self):
# Obtener los datos y ordenarlos
with sqlite3.connect('mi_base_de_datos3.db') as conexion:
cursor = conexion.cursor()
cursor.execute("SELECT * FROM registros ORDER BY GBT")
rows = cursor.fetchall()
self.actualizar_vista_treeview(rows)
#....................................................................................
def ordenar_por_cmf(self):
# Obtener los datos y ordenarlos
with sqlite3.connect('mi_base_de_datos3.db') as conexion:
cursor = conexion.cursor()
cursor.execute("SELECT * FROM registros ORDER BY CMF")
rows = cursor.fetchall()
self.actualizar_vista_treeview(rows)
#....................................................................................
def actualizar_vista_treeview(self, rows):
# Limpiar el Treeview antes de rellenarlo
for i in self.tabla.get_children():
self.tabla.delete(i)
# Insertar los nuevos datos ordenados
for row in rows:
estilo = ''
if row[4] == 'RET': # Suponiendo que 'HOGAR' es el quinto elemento en la fila
estilo = 'RET.Treeview'
elif row[4] == 'PRO':
estilo = 'PRO.Treeview'
elif row[4] == 'HOS':
estilo = 'HOS.Treeview'
elif row[4] == 'NEC':
estilo = 'NEC.Treeview'
elif row[4] == 'PRE':
estilo = 'PRE.Treeview'
self.tabla.insert('', 'end', values=row[1:], tags=estilo)
if estilo:
self.tabla.tag_configure(estilo, background=('light blue' if row[4] == 'RET' else
'yellow' if row[4] == 'HOS' else
'light green' if row[4] == 'NEC' else
'light grey' if row[4] == 'PRE' else
'light blue' if row[4] == 'PRO' else
'black'))
#....................................................................................
def actualizar_datos_gestacionales(self, event=None):
if self.validar_fecha(self.entries['FUM_FUSD'].get().strip()):
self.actualizar_fpp()
self.actualizar_eg()
# New: Calculate and update trimester based on EG
eg = float(self.entries['EG'].get().strip() or 0)
self.calcular_trim(eg)
#....................................................................................
def actualizar_fpp(self):
fpp = self.calcular_fpp()
if fpp:
self.entries['FPP'].delete(0, tk.END)
self.entries['FPP'].insert(0, fpp)
#....................................................................................
def actualizar_eg(self):
fecha_fum_fusd = self.entries['FUM_FUSD'].get().strip()
dias_adicionales = int(self.entries['DIAS'].get().strip() or 0)
semanas_adicionales = int(self.entries['SEM'].get().strip() or 0) * 7
if self.validar_fecha(fecha_fum_fusd):
fecha_fum_fusd = datetime.strptime(fecha_fum_fusd, "%Y-%m-%d")
total_dias = (datetime.now() - fecha_fum_fusd).days + dias_adicionales + semanas_adicionales
semanas = total_dias // 7
dias = total_dias % 7
self.entries['EG'].delete(0, tk.END)
self.entries['EG'].insert(0, f"{semanas}.{dias}")
self.calcular_trim(semanas + dias / 7) # Update Trim based on the new EG
#....................................................................................
def calcular_edad_evento(self, event):
ci = self.entries['CI'].get().strip()
if len(ci) >= 6:
try:
fecha_nacimiento = datetime.strptime(ci[:6], "%y%m%d")
edad = calcular_edad(fecha_nacimiento)
self.entries['EDAD'].delete(0, tk.END)
self.entries['EDAD'].insert(0, str(edad))
except ValueError:
pass
#....................................................................................
def calcular_fpp(self):
try:
fecha_fum_fusd = datetime.strptime(self.entries['FUM_FUSD'].get(), "%Y-%m-%d")
dias = int(self.entries['DIAS'].get() or 0)
sem = int(self.entries['SEM'].get() or 0)
fpp = fecha_fum_fusd + timedelta(days=280 - (dias + sem*7))
return fpp.strftime("%Y-%m-%d")
except ValueError:
return ""
#....................................................................................
def calcular_trim(self, eg):
"""Calculates and updates the trimester based on gestational age."""
if eg <= 12.6:
trim = 'I'
elif 13 <= eg <= 22.6:
trim = 'II'
elif eg >= 23:
trim = 'III'
else:
trim = '' # In case of an out-of-range or invalid EG value
self.entries['Trim'].delete(0, tk.END)
self.entries['Trim'].insert(0, trim)
#....................................................................................
def visualizar_registros(self):
for i in self.tabla.get_children():
self.tabla.delete(i)
with sqlite3.connect('mi_base_de_datos3.db') as conexion:
cursor = conexion.cursor()
cursor.execute("SELECT * FROM registros")
rows = cursor.fetchall()
for row in rows:
estilo = ''
if row[4] == 'RET': # Suponiendo que 'HOGAR' es el quinto elemento en la fila
estilo = 'RET.Treeview'
elif row[4] == 'PRO':
estilo = 'PRO.Treeview'
elif row[4] == 'HOS':
estilo = 'HOS.Treeview'
elif row[4] == 'NEC':
estilo = 'NEC.Treeview'
elif row[4] == 'PRE':
estilo = 'PRE.Treeview'
self.tabla.insert('', 'end', values=row[1:], tags=estilo)
if estilo:
self.tabla.tag_configure(estilo, background=('light blue' if row[4] == 'RET' else
'yellow' if row[4] == 'HOS' else
'light green' if row[4] == 'NEC' else
'light grey' if row[4] == 'PRE' else
'light blue' if row[4] == 'PRO' else
'black'))
#....................................................................................
def validar_ci_evento(self, event):
ci = self.entries['CI'].get().strip()
if not self.validar_ci(ci):
messagebox.showerror("Error de Validación", "El campo CI debe tener exactamente 11 dígitos y el penúltimo debe ser impar")
self.entries['CI'].delete(0, tk.END)
self.entries['CI'].focus_set()
#....................................................................................
def validar_ci(self, ci):
if len(ci) == 11 and ci.isdigit():
penultimo_digito = int(ci[-2])
return penultimo_digito % 2 != 0
return False
#....................................................................................
def validar_dias(self, event=None):
dias = self.entries['DIAS'].get().strip()
if dias: # Si hay algún valor, verifica que sea adecuado
if not dias.isdigit() or not (1 <= int(dias) <= 6):
messagebox.showerror("Error de Validación", "El campo DIAS debe estar en blanco o ser un número entre 1 y 6")
self.entries['DIAS'].delete(0, tk.END) # Borra el contenido incorrecto
self.entries['DIAS'].focus_set() # Devuelve el enfoque al campo DIAS
else:
# Si el valor es válido, actualizamos datos gestacionales.
self.actualizar_datos_gestacionales()
else:
# También actualizar si el campo se deja en blanco, lo que puede cambiar los cálculos.
self.actualizar_datos_gestacionales()
#....................................................................................
def validar_factores_de_riesgo(self):
clasif = self.entries['CLASIF'].get().strip()
factores_de_riesgo = self.entries['FACTORES_DE_RIESGO'].get().strip()
if clasif == 'Normal' and factores_de_riesgo:
messagebox.showerror("Error de Validación", "Si CLASIF es 'Normal', el campo FACTORES_DE_RIESGO debe estar vacío.")
self.entries['FACTORES_DE_RIESGO'].focus_set()
return False
elif clasif in ['ARO', 'BRO', 'CAV'] and not factores_de_riesgo:
messagebox.showerror("Error de Validación", "Si CLASIF es 'ARO', 'BRO' o 'CAV', el campo FACTORES_DE_RIESGO no puede estar vacío.")
self.entries['FACTORES_DE_RIESGO'].focus_set()
return False
return True
#....................................................................................
def validar_fecha_fum_fusd(self, event):
fecha = self.entries['FUM_FUSD'].get().strip()
if fecha:
if not self.validar_fecha(fecha):
messagebox.showerror("Error", "El campo FUM_FUSD debe tener el formato YYYY-MM-DD")
self.entries['FUM_FUSD'].delete(0, tk.END)
self.entries['FUM_FUSD'].focus_set()
#....................................................................................
def validar_fecha(self, fecha):
patron = r'\d{4}-\d{2}-\d{2}'
return re.match(patron, fecha)
#....................................................................................
def validar_clasif(self, clasif):
permitidos = ['Normal', 'ARO', 'BRO', 'CAV']
return clasif in permitidos
#....................................................................................
def validar_campos(self):
campos_obligatorios = ['GBT', 'CMF', 'CI', 'NOMBRE', 'APELLIDO1', 'APELLIDO2', 'CALLE', 'No_KM', 'BARRIO_O_REPARTO', 'FUM_FUSD', 'CLASIF']
for campo in campos_obligatorios:
if not self.entries[campo].get().strip():
messagebox.showerror("Error", f"El campo {campo} no puede estar vacío")
self.entries[campo].focus_set()
return False
if campo == 'CLASIF' and not self.validar_clasif(self.entries['CLASIF'].get().strip()):
messagebox.showerror("Error de Validación", "El campo CLASIF debe ser uno de los siguientes: Normal, ARO, BRO, CAV")
self.entries['CLASIF'].delete(0, tk.END)
self.entries['CLASIF'].focus_set()
return False
return True
root = tk.Tk()
app = Aplicacion(root)
root.mainloop()