1.
IMPORTS Y DEPENDENCIAS
python
import tkinter as tk
from tkinter import ttk, messagebox
import pickle
import os
from abc import ABC, abstractmethod
¿Qué hace?
• tkinter: Librería para crear interfaces gráficas
• pickle: Para guardar y cargar objetos Python en archivos
• os: Para verificar si archivos existen
• abc: Para crear clases abstractas (ABC = Abstract Base Class)
Explicación: "Estas son las herramientas básicas. Tkinter nos da botones y ventanas, pickle
nos permite guardar datos, y abc nos ayuda a organizar mejor el código con clases
abstractas."
2. CLASE ABSTRACTA PERSONA
python
class Persona(ABC):
@abstractmethod
def mostrar_info(self):
pass
¿Qué hace?
• Define una plantilla común para Usuario y Empresa
• Obliga a todas las subclases a implementar mostrar_info()
• No se puede crear objetos de Persona directamente
Explicación: "Es como un contrato. Dice: 'Cualquier persona en nuestro sistema debe poder
mostrar su información'. Pero es solo una plantilla, no se usa directamente."
3. CLASE USUARIO (hereda de Persona)
python
class Usuario(Persona):
def __init__(self, nombre, cedula, correo, contrasena_encriptada, titulos="",
experiencia=""):
[Link] = nombre
[Link] = cedula
[Link] = correo
self.contrasena_encriptada = contrasena_encriptada
[Link] = False
[Link] = titulos
[Link] = experiencia
def mostrar_info(self):
return f"Usuario: {[Link]}, Títulos: {[Link]}, Experiencia: {[Link]}"
¿Qué hace?
• Crea objetos de usuario con todos sus datos personales
• contratado=False por defecto (nadie está contratado al principio)
• Almacena títulos y experiencia para perfiles completos
• Implementa el método abstracto mostrar_info()
Explicación: "Cada usuario tiene cédula, correo, y ahora también títulos y experiencia. El
atributo contratado controla si ya tiene trabajo o está disponible."
4. CLASE USUARIOESTUDIANTE (hereda de Usuario)
python
class UsuarioEstudiante(Usuario):
def __init__(self, nombre, cedula, correo, contrasena_encriptada, universidad, titulos="",
experiencia=""):
super().__init__(nombre, cedula, correo, contrasena_encriptada, titulos, experiencia)
[Link] = universidad
def mostrar_info(self):
return f"Estudiante: {[Link]}, Universidad: {[Link]}, Títulos: {[Link]},
Experiencia: {[Link]}"
¿Qué hace?
• Añade el atributo universidad a un usuario normal
• Usa super().__init__() para reutilizar el constructor del padre
• Sobrescribe mostrar_info() para incluir la universidad
Explicación: "Un estudiante es un usuario con universidad. Hereda todo del usuario normal y
añade información extra. Esto evita duplicar código."
5. CLASE EMPRESA (hereda de Persona)
python
class Empresa(Persona):
def __init__(self, nombre_empresa, tipo_empresa, correo_empresa,
contrasena_encriptada, cualidades_requeridas=""):
self.nombre_empresa = nombre_empresa
self.tipo_empresa = tipo_empresa
self.correo_empresa = correo_empresa
self.contrasena_encriptada = contrasena_encriptada
[Link] = []
self.cualidades_requeridas = cualidades_requeridas
def mostrar_info(self):
return f"Empresa: {self.nombre_empresa}, Busca: {self.cualidades_requeridas}"
¿Qué hace?
• Representa una empresa que busca empleados
• empleados=[] lista vacía para almacenar quiénes ha contratado
• cualidades_requeridas especifica qué tipo de personas busca
• También implementa mostrar_info() como Persona
Explicación: "Las empresas tienen lista de empleados y especifican qué cualidades buscan.
Esto ayuda a hacer mejor 'match' entre oferta y demanda."
6. CLASE EMPRESATECNOLÓGICA (hereda de Empresa)
python
class EmpresaTecnologica(Empresa):
def __init__(self, nombre_empresa, tipo_empresa, correo_empresa,
contrasena_encriptada, tecnologia_principal, cualidades_requeridas=""):
super().__init__(nombre_empresa, tipo_empresa, correo_empresa,
contrasena_encriptada, cualidades_requeridas)
self.tecnologia_principal = tecnologia_principal
def mostrar_info(self):
return f"Empresa Tecnológica: {self.nombre_empresa}, Tecnología:
{self.tecnologia_principal}, Busca: {self.cualidades_requeridas}"
¿Qué hace?
• Empresa especializada en tecnología
• Añade atributo tecnologia_principal (ej: "Python", "Java")
• Muestra información específica de empresa tecnológica
Explicación: "Empresas tecnológicas tienen tecnología principal. Esto permite especialización:
una empresa de Python busca programadores Python."
7. CLASE CONEXIONUNIVERSITARIA (Gestión de datos)
python
class ConexionUniversitaria:
def __init__(self):
[Link] = [] # Lista de todos los usuarios
[Link] = [] # Lista de todas las empresas
self.cargar_datos() # Carga datos anteriores al iniciar
def encriptar(self, texto):
return [Link](texto) # Convierte texto a bytes
def desencriptar(self, dato):
return [Link](dato) # Convierte bytes a texto
def guardar_datos(self):
with open("conexion_data.pkl", "wb") as f:
[Link]({"usuarios": [Link],
"empresas": [Link]}, f)
def cargar_datos(self):
if [Link]("conexion_data.pkl"):
with open("conexion_data.pkl", "rb") as f:
data = [Link](f)
[Link] = [Link]("usuarios", [])
[Link] = [Link]("empresas", [])
¿Qué hace?
• __init__: Inicializa listas vacías y carga datos existentes
• encriptar/desencriptar: Convierte contraseñas (en realidad serializa)
• guardar_datos: Guarda todas las listas en archivo .pkl
• cargar_datos: Recupera datos del archivo si existe
Explicación: "Es el cerebro del sistema. Maneja todas las listas, guarda cuando cerramos, carga
cuando abrimos. Así los datos no se pierden."
8. VENTANA DE LOGIN (LoginWindow)
python
class LoginWindow:
def __init__(self, master, app):
[Link]("Iniciar Sesión")
[Link]("350x350")
# Crear etiquetas y campos
[Link](master, text="Correo").pack(pady=5)
self.entry_correo = [Link](master)
self.entry_correo.pack()
[Link](master, text="Contraseña").pack(pady=5)
self.entry_contra = [Link](master, show="*")
self.entry_contra.pack()
# Botones
[Link](master, text="Ingresar como Usuario",
command=self.login_usuario).pack(pady=10)
[Link](master, text="Ingresar como Empresa",
command=self.login_empresa).pack(pady=10)
[Link](master, text="Registrar Usuario",
command=self.registrar_usuario).pack(pady=10)
[Link](master, text="Registrar Empresa",
command=self.registrar_empresa).pack(pady=10)
¿Qué hace?
• Crea la ventana inicial con título y tamaño
• Añade campos para correo y contraseña
• Crea 4 botones con diferentes funciones
• show="*" oculta la contraseña mientras se escribe
Explicación: "Primera pantalla que ve el usuario. Pide credenciales y ofrece opciones. Los
botones están conectados a funciones específicas."
9. FUNCIONES DE LOGIN
python
def login_usuario(self):
c = self.entry_correo.get() # Obtiene texto del campo
pw = self.entry_contra.get()
for u in [Link]: # Busca en todos los usuarios
if [Link] == c and [Link](u.contrasena_encriptada) == pw:
UserDashboard([Link]([Link]), [Link], u)
return
[Link]("Error", "Credenciales inválidas")
def login_empresa(self):
# Similar pero busca en empresas
¿Qué hace?
1. Obtiene lo que el usuario escribió
2. Busca en la lista de usuarios registrados
3. Compara correo y contraseña desencriptada
4. Si encuentra coincidencia, abre el dashboard
5. Si no, muestra error
Explicación: "Verifica credenciales. Si son correctas, pasa al panel principal. Si no, avisa del
error. Simple pero efectivo."
10. REGISTRO DE USUARIO (RegistroUsuario)
python
class RegistroUsuario:
def __init__(self, master, app):
# ... configuración de ventana ...
[Link](master, text="Tipo de Usuario").pack(pady=5)
self.tipo_var = [Link](value="General")
[Link](master, textvariable=self.tipo_var,
values=["General", "Estudiante"]).pack()
# Campos básicos + extendidos
campos = ["Nombre", "Cédula", "Correo", "Contraseña",
"Títulos", "Experiencia"]
# Campo dinámico para universidad (solo estudiantes)
self.label_universidad = [Link](master, text="Universidad")
self.entry_universidad = [Link](master)
# Conectar evento para mostrar/ocultar campo
self.tipo_var.trace("w", self.actualizar_campos)
¿Qué hace?
• Crea formulario con 6 campos básicos
• Combobox para elegir tipo de usuario
• Campo "Universidad" aparece solo si se selecciona "Estudiante"
• trace("w", ...) escucha cambios en el combobox
Explicación: "Formulario inteligente. Si eliges 'Estudiante', aparece campo universidad. Si
eliges 'General', desaparece. Se adapta al contexto."
11. GUARDAR REGISTRO DE USUARIO
python
def guardar(self):
# Obtiene todos los datos de los campos
datos = {k: [Link]() for k, v in [Link]()}
# Validación: ningún campo vacío
if "" in [Link]():
[Link]("Error", "Todos los campos son obligatorios")
return
# Encripta la contraseña
enc = [Link](datos["Contraseña"])
# Crea objeto según tipo
if self.tipo_var.get() == "Estudiante":
usuario = UsuarioEstudiante(datos["Nombre"], datos["Cédula"],
datos["Correo"], enc,
self.entry_universidad.get(),
datos["Títulos"], datos["Experiencia"])
else:
usuario = Usuario(datos["Nombre"], datos["Cédula"],
datos["Correo"], enc,
datos["Títulos"], datos["Experiencia"])
# Guarda en sistema
[Link](usuario)
[Link].guardar_datos() # Persiste inmediatamente
[Link]("Éxito", "Usuario registrado")
[Link]() # Cierra ventana
¿Qué hace?
1. Recoge datos de todos los campos
2. Valida que no haya campos vacíos
3. Encripta la contraseña
4. Crea objeto Usuario o UsuarioEstudiante
5. Añade a la lista general
6. Guarda en archivo
7. Informa éxito y cierra
Explicación: "Toma todos los datos, los valida, crea el objeto correcto, lo guarda en memoria y
archivo, y cierra el formulario. Todo en un flujo."
12. DASHBOARD DE USUARIO (UserDashboard)
python
class UserDashboard:
def __init__(self, master, app, user):
[Link]("Panel Usuario")
# Saludo personalizado
[Link](master, text=f"Bienvenido {[Link]}").pack(pady=10)
# Estado (contratado/disponible)
estado = "Contratado" if [Link] else "Disponible"
[Link](master, text=f"Estado: {estado}").pack(pady=10)
# Información completa usando polimorfismo
[Link](master, text=user.mostrar_info()).pack(pady=10)
¿Qué hace?
• Muestra nombre del usuario
• Indica si está contratado o disponible
• Muestra información completa con mostrar_info()
• Usa polimorfismo: funciona igual para usuarios y estudiantes
Explicación: "Panel personalizado. Muestra estado laboral y toda la información del
perfil. user.mostrar_info() llama al método correcto automáticamente."
13. DASHBOARD DE EMPRESA (EmpresaDashboard)
python
class EmpresaDashboard:
def __init__(self, master, app, empresa):
# ... configuración similar ...
[Link](master, text="Ver Usuarios Disponibles",
command=self.ver_disponibles).pack(pady=10)
[Link](master, text="Ver Mis Contratados",
command=self.ver_contratados).pack(pady=10)
¿Qué hace?
• Muestra información de la empresa
• Botón para ver usuarios disponibles para contratar
• Botón para ver usuarios ya contratados
Explicación: "Panel de control empresarial. Desde aquí pueden buscar talento y gestionar sus
contrataciones."
14. VER USUARIOS DISPONIBLES
python
def ver_disponibles(self):
v = [Link]([Link]) # Nueva ventana
[Link]("Usuarios Disponibles")
# Crear tabla con 5 columnas
tabla = [Link](v, columns=("Nombre", "Correo", "Cédula",
"Títulos", "Experiencia"),
show="headings")
# Configurar encabezados
for c in ("Nombre", "Correo", "Cédula", "Títulos", "Experiencia"):
[Link](c, text=c)
# Llenar tabla solo con usuarios NO contratados
for u in [Link]:
if not [Link]: # ← Filtro clave
[Link]("", "end", iid=[Link],
values=([Link], [Link], [Link],
[Link], [Link]))
[Link](fill="both", expand=True)
# Botón de contratar
def contratar():
sel = [Link]() # Obtiene selección
if sel:
cid = sel[0] # Cédula del usuario seleccionado
for u in [Link]:
if [Link] == cid:
[Link] = True # Cambia estado
[Link](u) # Añade a empresa
[Link].guardar_datos() # Guarda cambios
[Link]("Éxito", "Usuario contratado")
[Link]() # Cierra ventana
return
[Link](v, text="Contratar", command=contratar).pack(pady=10)
¿Qué hace?
1. Abre nueva ventana con tabla
2. Muestra solo usuarios con contratado=False
3. Permite seleccionar un usuario
4. Al contratar: cambia estado, añade a empleados, guarda
5. Cierra ventana e informa éxito
Explicación: "Tabla inteligente que filtra solo disponibles. Al contratar, actualiza tres lugares:
estado del usuario, lista de empleados, y archivo de datos."
15. MAIN Y EJECUCIÓN
python
root = [Link]() # Crea ventana principal
app = ConexionUniversitaria() # Crea gestor de datos
LoginWindow(root, app) # Muestra ventana de login
[Link]() # Inicia ciclo principal de tkinter
¿Qué hace?
• [Link](): Crea la ventana raíz de tkinter
• ConexionUniversitaria(): Inicializa el sistema de datos
• LoginWindow(): Muestra la primera pantalla
• mainloop(): Mantiene el programa corriendo, escuchando eventos
Explicación: "Punto de entrada. Crea todo el sistema y lo pone en marcha. mainloop() es
como un motor que mantiene vivo el programa."
RESUMEN DE FLUJO COMPLETO:
1. Inicio → main() crea ventana y sistema
2. Login → Ventana con 4 opciones
3. Registro → Formulario dinámico según tipo
4. Dashboard → Panel personalizado según rol
5. Búsqueda → Tabla filtrada de disponibles
6. Contratación → Cambia estado y guarda
7. Persistencia → Guarda automáticamente en archivo
EXPLICACIÓN COMPLETA DEL CÓDIGO - PARTE POR PARTE
1. IMPORTS Y DEPENDENCIAS
python
import tkinter as tk
from tkinter import ttk, messagebox
import pickle
import os
from abc import ABC, abstractmethod
¿Qué hace?
• tkinter: Librería para crear interfaces gráficas
• pickle: Para guardar y cargar objetos Python en archivos
• os: Para verificar si archivos existen
• abc: Para crear clases abstractas (ABC = Abstract Base Class)
Explicación: "Estas son las herramientas básicas. Tkinter nos da botones y ventanas, pickle
nos permite guardar datos, y abc nos ayuda a organizar mejor el código con clases
abstractas."
2. CLASE ABSTRACTA PERSONA
python
class Persona(ABC):
@abstractmethod
def mostrar_info(self):
pass
¿Qué hace?
• Define una plantilla común para Usuario y Empresa
• Obliga a todas las subclases a implementar mostrar_info()
• No se puede crear objetos de Persona directamente
Explicación: "Es como un contrato. Dice: 'Cualquier persona en nuestro sistema debe poder
mostrar su información'. Pero es solo una plantilla, no se usa directamente."
3. CLASE USUARIO (hereda de Persona)
python
class Usuario(Persona):
def __init__(self, nombre, cedula, correo, contrasena_encriptada, titulos="",
experiencia=""):
[Link] = nombre
[Link] = cedula
[Link] = correo
self.contrasena_encriptada = contrasena_encriptada
[Link] = False
[Link] = titulos
[Link] = experiencia
def mostrar_info(self):
return f"Usuario: {[Link]}, Títulos: {[Link]}, Experiencia: {[Link]}"
¿Qué hace?
• Crea objetos de usuario con todos sus datos personales
• contratado=False por defecto (nadie está contratado al principio)
• Almacena títulos y experiencia para perfiles completos
• Implementa el método abstracto mostrar_info()
Explicación: "Cada usuario tiene cédula, correo, y ahora también títulos y experiencia. El
atributo contratado controla si ya tiene trabajo o está disponible."
4. CLASE USUARIOESTUDIANTE (hereda de Usuario)
python
class UsuarioEstudiante(Usuario):
def __init__(self, nombre, cedula, correo, contrasena_encriptada, universidad, titulos="",
experiencia=""):
super().__init__(nombre, cedula, correo, contrasena_encriptada, titulos, experiencia)
[Link] = universidad
def mostrar_info(self):
return f"Estudiante: {[Link]}, Universidad: {[Link]}, Títulos: {[Link]},
Experiencia: {[Link]}"
¿Qué hace?
• Añade el atributo universidad a un usuario normal
• Usa super().__init__() para reutilizar el constructor del padre
• Sobrescribe mostrar_info() para incluir la universidad
Explicación: "Un estudiante es un usuario con universidad. Hereda todo del usuario normal y
añade información extra. Esto evita duplicar código."
5. CLASE EMPRESA (hereda de Persona)
python
class Empresa(Persona):
def __init__(self, nombre_empresa, tipo_empresa, correo_empresa,
contrasena_encriptada, cualidades_requeridas=""):
self.nombre_empresa = nombre_empresa
self.tipo_empresa = tipo_empresa
self.correo_empresa = correo_empresa
self.contrasena_encriptada = contrasena_encriptada
[Link] = []
self.cualidades_requeridas = cualidades_requeridas
def mostrar_info(self):
return f"Empresa: {self.nombre_empresa}, Busca: {self.cualidades_requeridas}"
¿Qué hace?
• Representa una empresa que busca empleados
• empleados=[] lista vacía para almacenar quiénes ha contratado
• cualidades_requeridas especifica qué tipo de personas busca
• También implementa mostrar_info() como Persona
Explicación: "Las empresas tienen lista de empleados y especifican qué cualidades buscan.
Esto ayuda a hacer mejor 'match' entre oferta y demanda."
6. CLASE EMPRESATECNOLÓGICA (hereda de Empresa)
python
class EmpresaTecnologica(Empresa):
def __init__(self, nombre_empresa, tipo_empresa, correo_empresa,
contrasena_encriptada, tecnologia_principal, cualidades_requeridas=""):
super().__init__(nombre_empresa, tipo_empresa, correo_empresa,
contrasena_encriptada, cualidades_requeridas)
self.tecnologia_principal = tecnologia_principal
def mostrar_info(self):
return f"Empresa Tecnológica: {self.nombre_empresa}, Tecnología:
{self.tecnologia_principal}, Busca: {self.cualidades_requeridas}"
¿Qué hace?
• Empresa especializada en tecnología
• Añade atributo tecnologia_principal (ej: "Python", "Java")
• Muestra información específica de empresa tecnológica
Explicación: "Empresas tecnológicas tienen tecnología principal. Esto permite especialización:
una empresa de Python busca programadores Python."
7. CLASE CONEXIONUNIVERSITARIA (Gestión de datos)
python
class ConexionUniversitaria:
def __init__(self):
[Link] = [] # Lista de todos los usuarios
[Link] = [] # Lista de todas las empresas
self.cargar_datos() # Carga datos anteriores al iniciar
def encriptar(self, texto):
return [Link](texto) # Convierte texto a bytes
def desencriptar(self, dato):
return [Link](dato) # Convierte bytes a texto
def guardar_datos(self):
with open("conexion_data.pkl", "wb") as f:
[Link]({"usuarios": [Link],
"empresas": [Link]}, f)
def cargar_datos(self):
if [Link]("conexion_data.pkl"):
with open("conexion_data.pkl", "rb") as f:
data = [Link](f)
[Link] = [Link]("usuarios", [])
[Link] = [Link]("empresas", [])
¿Qué hace?
• __init__: Inicializa listas vacías y carga datos existentes
• encriptar/desencriptar: Convierte contraseñas (en realidad serializa)
• guardar_datos: Guarda todas las listas en archivo .pkl
• cargar_datos: Recupera datos del archivo si existe
Explicación: "Es el cerebro del sistema. Maneja todas las listas, guarda cuando cerramos, carga
cuando abrimos. Así los datos no se pierden."
8. VENTANA DE LOGIN (LoginWindow)
python
class LoginWindow:
def __init__(self, master, app):
[Link]("Iniciar Sesión")
[Link]("350x350")
# Crear etiquetas y campos
[Link](master, text="Correo").pack(pady=5)
self.entry_correo = [Link](master)
self.entry_correo.pack()
[Link](master, text="Contraseña").pack(pady=5)
self.entry_contra = [Link](master, show="*")
self.entry_contra.pack()
# Botones
[Link](master, text="Ingresar como Usuario",
command=self.login_usuario).pack(pady=10)
[Link](master, text="Ingresar como Empresa",
command=self.login_empresa).pack(pady=10)
[Link](master, text="Registrar Usuario",
command=self.registrar_usuario).pack(pady=10)
[Link](master, text="Registrar Empresa",
command=self.registrar_empresa).pack(pady=10)
¿Qué hace?
• Crea la ventana inicial con título y tamaño
• Añade campos para correo y contraseña
• Crea 4 botones con diferentes funciones
• show="*" oculta la contraseña mientras se escribe
Explicación: "Primera pantalla que ve el usuario. Pide credenciales y ofrece opciones. Los
botones están conectados a funciones específicas."
9. FUNCIONES DE LOGIN
python
def login_usuario(self):
c = self.entry_correo.get() # Obtiene texto del campo
pw = self.entry_contra.get()
for u in [Link]: # Busca en todos los usuarios
if [Link] == c and [Link](u.contrasena_encriptada) == pw:
UserDashboard([Link]([Link]), [Link], u)
return
[Link]("Error", "Credenciales inválidas")
def login_empresa(self):
# Similar pero busca en empresas
¿Qué hace?
1. Obtiene lo que el usuario escribió
2. Busca en la lista de usuarios registrados
3. Compara correo y contraseña desencriptada
4. Si encuentra coincidencia, abre el dashboard
5. Si no, muestra error
Explicación: "Verifica credenciales. Si son correctas, pasa al panel principal. Si no, avisa del
error. Simple pero efectivo."
10. REGISTRO DE USUARIO (RegistroUsuario)
python
class RegistroUsuario:
def __init__(self, master, app):
# ... configuración de ventana ...
[Link](master, text="Tipo de Usuario").pack(pady=5)
self.tipo_var = [Link](value="General")
[Link](master, textvariable=self.tipo_var,
values=["General", "Estudiante"]).pack()
# Campos básicos + extendidos
campos = ["Nombre", "Cédula", "Correo", "Contraseña",
"Títulos", "Experiencia"]
# Campo dinámico para universidad (solo estudiantes)
self.label_universidad = [Link](master, text="Universidad")
self.entry_universidad = [Link](master)
# Conectar evento para mostrar/ocultar campo
self.tipo_var.trace("w", self.actualizar_campos)
¿Qué hace?
• Crea formulario con 6 campos básicos
• Combobox para elegir tipo de usuario
• Campo "Universidad" aparece solo si se selecciona "Estudiante"
• trace("w", ...) escucha cambios en el combobox
Explicación: "Formulario inteligente. Si eliges 'Estudiante', aparece campo universidad. Si
eliges 'General', desaparece. Se adapta al contexto."
11. GUARDAR REGISTRO DE USUARIO
python
def guardar(self):
# Obtiene todos los datos de los campos
datos = {k: [Link]() for k, v in [Link]()}
# Validación: ningún campo vacío
if "" in [Link]():
[Link]("Error", "Todos los campos son obligatorios")
return
# Encripta la contraseña
enc = [Link](datos["Contraseña"])
# Crea objeto según tipo
if self.tipo_var.get() == "Estudiante":
usuario = UsuarioEstudiante(datos["Nombre"], datos["Cédula"],
datos["Correo"], enc,
self.entry_universidad.get(),
datos["Títulos"], datos["Experiencia"])
else:
usuario = Usuario(datos["Nombre"], datos["Cédula"],
datos["Correo"], enc,
datos["Títulos"], datos["Experiencia"])
# Guarda en sistema
[Link](usuario)
[Link].guardar_datos() # Persiste inmediatamente
[Link]("Éxito", "Usuario registrado")
[Link]() # Cierra ventana
¿Qué hace?
1. Recoge datos de todos los campos
2. Valida que no haya campos vacíos
3. Encripta la contraseña
4. Crea objeto Usuario o UsuarioEstudiante
5. Añade a la lista general
6. Guarda en archivo
7. Informa éxito y cierra
Explicación: "Toma todos los datos, los valida, crea el objeto correcto, lo guarda en memoria y
archivo, y cierra el formulario. Todo en un flujo."
12. DASHBOARD DE USUARIO (UserDashboard)
python
class UserDashboard:
def __init__(self, master, app, user):
[Link]("Panel Usuario")
# Saludo personalizado
[Link](master, text=f"Bienvenido {[Link]}").pack(pady=10)
# Estado (contratado/disponible)
estado = "Contratado" if [Link] else "Disponible"
[Link](master, text=f"Estado: {estado}").pack(pady=10)
# Información completa usando polimorfismo
[Link](master, text=user.mostrar_info()).pack(pady=10)
¿Qué hace?
• Muestra nombre del usuario
• Indica si está contratado o disponible
• Muestra información completa con mostrar_info()
• Usa polimorfismo: funciona igual para usuarios y estudiantes
Explicación: "Panel personalizado. Muestra estado laboral y toda la información del
perfil. user.mostrar_info() llama al método correcto automáticamente."
13. DASHBOARD DE EMPRESA (EmpresaDashboard)
python
class EmpresaDashboard:
def __init__(self, master, app, empresa):
# ... configuración similar ...
[Link](master, text="Ver Usuarios Disponibles",
command=self.ver_disponibles).pack(pady=10)
[Link](master, text="Ver Mis Contratados",
command=self.ver_contratados).pack(pady=10)
¿Qué hace?
• Muestra información de la empresa
• Botón para ver usuarios disponibles para contratar
• Botón para ver usuarios ya contratados
Explicación: "Panel de control empresarial. Desde aquí pueden buscar talento y gestionar sus
contrataciones."
14. VER USUARIOS DISPONIBLES
python
def ver_disponibles(self):
v = [Link]([Link]) # Nueva ventana
[Link]("Usuarios Disponibles")
# Crear tabla con 5 columnas
tabla = [Link](v, columns=("Nombre", "Correo", "Cédula",
"Títulos", "Experiencia"),
show="headings")
# Configurar encabezados
for c in ("Nombre", "Correo", "Cédula", "Títulos", "Experiencia"):
[Link](c, text=c)
# Llenar tabla solo con usuarios NO contratados
for u in [Link]:
if not [Link]: # ← Filtro clave
[Link]("", "end", iid=[Link],
values=([Link], [Link], [Link],
[Link], [Link]))
[Link](fill="both", expand=True)
# Botón de contratar
def contratar():
sel = [Link]() # Obtiene selección
if sel:
cid = sel[0] # Cédula del usuario seleccionado
for u in [Link]:
if [Link] == cid:
[Link] = True # Cambia estado
[Link](u) # Añade a empresa
[Link].guardar_datos() # Guarda cambios
[Link]("Éxito", "Usuario contratado")
[Link]() # Cierra ventana
return
[Link](v, text="Contratar", command=contratar).pack(pady=10)
¿Qué hace?
1. Abre nueva ventana con tabla
2. Muestra solo usuarios con contratado=False
3. Permite seleccionar un usuario
4. Al contratar: cambia estado, añade a empleados, guarda
5. Cierra ventana e informa éxito
Explicación: "Tabla inteligente que filtra solo disponibles. Al contratar, actualiza tres lugares:
estado del usuario, lista de empleados, y archivo de datos."
15. MAIN Y EJECUCIÓN
python
root = [Link]() # Crea ventana principal
app = ConexionUniversitaria() # Crea gestor de datos
LoginWindow(root, app) # Muestra ventana de login
[Link]() # Inicia ciclo principal de tkinter
¿Qué hace?
• [Link](): Crea la ventana raíz de tkinter
• ConexionUniversitaria(): Inicializa el sistema de datos
• LoginWindow(): Muestra la primera pantalla
• mainloop(): Mantiene el programa corriendo, escuchando eventos
Explicación: "Punto de entrada. Crea todo el sistema y lo pone en marcha. mainloop() es
como un motor que mantiene vivo el programa."
RESUMEN DE FLUJO COMPLETO:
1. Inicio → main() crea ventana y sistema
2. Login → Ventana con 4 opciones
3. Registro → Formulario dinámico según tipo
4. Dashboard → Panel personalizado según rol
5. Búsqueda → Tabla filtrada de disponibles
6. Contratación → Cambia estado y guarda
7. Persistencia → Guarda automáticamente en archivo