Como crear un generador de curriculum en Python

1. Estructura del proyecto

2. models/curriculum_base -Clase.

3. models/templates.py — Plantillas heredadas (LinkedIn, Europass, Minimalista, Moderna).

4. app.py— Servidor Flask listo para desplegar.

5. HTML integrable en tu web (formulario + vista previa) HTML

(Ojo: en resumen faltaba paréntesis en oninput, mejor usar oninput="onFormChange()" como en el resto.)

6, JavaScript con autosave + vista previa en tiempo real (muy comentado)




Curso de Programación Orientada a Objetos






Curso de Programación Orientada a Objetos

Guía didáctica en 10 lecciones

por Daniel Caraballo

danielcaraballo.es

Índice

  1. Clases
  2. Objetos
  3. Atributos y métodos
  4. Abstracción
  5. Encapsulamiento
  6. Herencia
  7. Polimorfismo
  8. Clases abstractas
  9. Principios SOLID
  10. Patrones de diseño

1. Clases en Programación Orientada a Objetos

¿Qué es una clase?

Una clase es un molde o plantilla que define cómo serán los objetos.

Dentro de una clase se definen:

  • Atributos (datos)
  • Métodos (acciones)

Es como un plano que describe cómo construir algo.

Ejemplo de una clase en Python

class Persona:
    def __init__(self, nombre, edad):
        self.nombre = nombre      # Atributo
        self.edad = edad          # Atributo

    def saludar(self):            # Método
        return f"Hola, soy {self.nombre}"

2. Objetos en Programación Orientada a Objetos

¿Qué es un objeto?

Un objeto es una instancia de una clase.

Si la clase es un plano, el objeto es la casa construida con ese plano.

Características de un objeto

  • Atributos: datos propios del objeto.
  • Métodos: acciones que puede realizar.
  • Estado: cómo se encuentra en un momento dado.
  • Identidad: cada objeto es único en memoria.

Ejemplo de creación de objetos

class Persona:
    def __init__(self, nombre, edad):
        self.nombre = nombre
        self.edad = edad

# Creamos dos objetos distintos
persona1 = Persona("Ana", 30)
persona2 = Persona("Luis", 25)

print(persona1.nombre)  # Ana
print(persona2.nombre)  # Luis

3. Atributos y Métodos

¿Qué son los atributos?

Los atributos son las características o datos que tiene un objeto.

Por ejemplo, una persona puede tener:

  • nombre
  • edad
  • altura

Cada objeto tendrá sus propios valores para esos atributos.

¿Qué son los métodos?

Los métodos son las acciones que un objeto puede realizar.

Siguiendo el ejemplo de una persona:

  • saludar()
  • caminar()
  • hablar()

Los métodos son funciones que viven dentro de una clase.

Ejemplo de atributos y métodos en Python

class Coche:
    def __init__(self, marca, velocidad):
        self.marca = marca          # Atributo
        self.velocidad = velocidad  # Atributo

    def acelerar(self):             # Método
        self.velocidad += 10
        return f"Velocidad actual: {self.velocidad} km/h"

# Creamos un objeto
mi_coche = Coche("Toyota", 120)

print(mi_coche.acelerar())  # Velocidad actual: 130 km/h

4. Abstracción

¿Qué es la abstracción?

La abstracción consiste en centrarse solo en lo importante y ocultar los detalles innecesarios.

Es como usar un coche: no necesitas saber cómo funciona el motor, solo cómo conducirlo.

Ejemplo de abstracción en Python

class Cafetera:
    def __init__(self):
        self.agua = 100

    def hacer_cafe(self):
        # El usuario no ve estos detalles internos
        self.agua -= 10
        return "Café listo"

# El usuario solo usa el método, sin saber cómo funciona dentro
cafetera = Cafetera()
print(cafetera.hacer_cafe())

¿Por qué es útil la abstracción?

  • Crear código más simple de usar
  • Ocultar detalles complejos
  • Evitar errores del usuario
  • Reutilizar componentes sin conocer su interior

5. Encapsulamiento

¿Qué es el encapsulamiento?

El encapsulamiento consiste en proteger los datos internos de un objeto para evitar que sean modificados directamente desde fuera.

Es como una caja fuerte: solo se accede a ella mediante métodos.

Modificadores de acceso en Python

Python usa una convención:

  • atributo → público
  • _atributo → protegido
  • __atributo → privado

Ejemplo de encapsulamiento en Python

class CuentaBancaria:
    def __init__(self, saldo):
        self.__saldo = saldo   # Atributo privado

    def depositar(self, cantidad):
        self.__saldo += cantidad

    def obtener_saldo(self):
        return self.__saldo

cuenta = CuentaBancaria(100)
cuenta.depositar(50)
print(cuenta.obtener_saldo())  # 150

6. Herencia

¿Qué es la herencia?

La herencia permite crear nuevas clases basadas en clases existentes.

La clase hija hereda atributos y métodos de la clase padre.

Ventajas de la herencia

  • Reutilizar código
  • Evitar duplicación
  • Crear jerarquías lógicas
  • Extender funcionalidades fácilmente

Ejemplo de herencia en Python

class Animal:
    def __init__(self, nombre):
        self.nombre = nombre

    def hacer_sonido(self):
        return "Sonido genérico"

# Clase hija que hereda de Animal
class Perro(Animal):
    def hacer_sonido(self):
        return "Guau!"

mi_perro = Perro("Toby")
print(mi_perro.nombre)          # Toby
print(mi_perro.hacer_sonido())  # Guau!

7. Polimorfismo

¿Qué es el polimorfismo?

El polimorfismo permite que diferentes clases respondan al mismo método, pero cada una a su manera.

Por ejemplo:

  • Perro.hacer_sonido() → «Guau»
  • Gato.hacer_sonido() → «Miau»

Ventajas del polimorfismo

  • Escribir código más flexible
  • Reutilizar funciones que aceptan distintos tipos
  • Evitar condicionales innecesarios
  • Extender comportamientos sin modificar código existente

Ejemplo de polimorfismo en Python

class Animal:
    def hacer_sonido(self):
        return "Sonido genérico"

class Perro(Animal):
    def hacer_sonido(self):
        return "Guau!"

class Gato(Animal):
    def hacer_sonido(self):
        return "Miau!"

# Función que usa polimorfismo
def reproducir_sonido(animal):
    print(animal.hacer_sonido())

reproducir_sonido(Perro())  # Guau!
reproducir_sonido(Gato())   # Miau!

8. Clases Abstractas

¿Qué es una clase abstracta?

Una clase abstracta es una clase que no se puede instanciar directamente.

Sirve como modelo para otras clases y define métodos que las clases hijas deben implementar.

¿Para qué sirve una clase abstracta?

  • Definir una estructura común
  • Obligar a las clases hijas a implementar ciertos métodos
  • Evitar instanciar clases incompletas
  • Organizar jerarquías más claras

Ejemplo de clase abstracta en Python

from abc import ABC, abstractmethod

# Clase abstracta
class Animal(ABC):

    @abstractmethod
    def hacer_sonido(self):
        pass

# Clase hija que implementa el método abstracto
class Perro(Animal):
    def hacer_sonido(self):
        return "Guau!"

mi_perro = Perro()
print(mi_perro.hacer_sonido())  # Guau!

9. Principios SOLID

¿Qué es SOLID?

SOLID es un conjunto de 5 principios que ayudan a escribir código más limpio, mantenible y escalable.

  • S — Single Responsibility Principle
  • O — Open/Closed Principle
  • L — Liskov Substitution Principle
  • I — Interface Segregation Principle
  • D — Dependency Inversion Principle

S — Principio de Responsabilidad Única

Una clase debe tener una sola razón para cambiar.

O — Principio Abierto/Cerrado

Una clase debe estar abierta a extensión y cerrada a modificación.

L — Principio de Sustitución de Liskov

Una clase hija debe poder sustituir a su clase padre sin romper el programa.

I — Principio de Segregación de Interfaces

Es mejor tener muchas interfaces pequeñas que una grande.

D — Principio de Inversión de Dependencias

Las clases deben depender de abstracciones, no de implementaciones concretas.

Ejemplo simple de SOLID en Python

# Ejemplo del principio S (Responsabilidad Única)

class Reporte:
    def generar(self):
        return "Datos del reporte"

class ReportePrinter:
    def imprimir(self, reporte):
        print(reporte.generar())

printer = ReportePrinter()
printer.imprimir(Reporte())

10. Patrones de Diseño

¿Qué son los patrones de diseño?

Los patrones de diseño son soluciones reutilizables a problemas comunes en el desarrollo de software.

No son código exacto, sino modelos que puedes adaptar.

Se dividen en:

  • Creacionales — cómo crear objetos
  • Estructurales — cómo organizar clases
  • Comportamiento — cómo interactúan los objetos

Patrones Creacionales

  • Singleton — solo una instancia
  • Factory Method — crea objetos sin especificar la clase exacta
  • Builder — construye objetos paso a paso
# Ejemplo simple de Singleton en Python

class Config:
    _instancia = None

    def __new__(cls):
        if cls._instancia is None:
            cls._instancia = super().__new__(cls)
        return cls._instancia

c1 = Config()
c2 = Config()

print(c1 is c2)  # True

Patrones Estructurales

  • Adapter — adapta una interfaz a otra
  • Decorator — añade funcionalidades sin modificar la clase
  • Facade — simplifica sistemas complejos
# Ejemplo simple de Decorator

def mayusculas(func):
    def wrapper():
        return func().upper()
    return wrapper

@mayusculas
def saludar():
    return "hola"

print(saludar())  # HOLA

Patrones de Comportamiento

  • Observer — notifica cambios a múltiples objetos
  • Strategy — intercambia algoritmos fácilmente
  • Command — encapsula acciones como objetos
# Ejemplo simple de Strategy

class EstrategiaA:
    def ejecutar(self):
        return "Estrategia A"

class EstrategiaB:
    def ejecutar(self):
        return "Estrategia B"

class Contexto:
    def __init__(self, estrategia):
        self.estrategia = estrategia

    def operar(self):
        return self.estrategia.ejecutar()

ctx = Contexto(EstrategiaA())
print(ctx.operar())  # Estrategia A





Pon a prueba tu Python: ejercicios del bucle for


🧩 Ejercicios interactivos

Ejercicio 1: Imprime los números del 10 al 1 en orden inverso.

for i in range(10, 0, -1):
    print(i)

Ejercicio 2: Muestra solo los nombres con más de 4 letras.

nombres = ["Ana", "Roberto", "Luis", "Marta"]
for nombre in nombres:
    if len(nombre) > 4:
        print(nombre)

Ejercicio 3: Usa enumerate() para mostrar índice y valor.

frutas = ["manzana", "pera", "uva"]
for indice, fruta in enumerate(frutas):
    print(indice, fruta)

Ejercicio 4: Crea una lista con los cuadrados del 1 al 10.

cuadrados = [x*x for x in range(1, 11)]
print(cuadrados)

❓ Preguntas frecuentes (FAQ)

1. ¿Por qué mi bucle for no se ejecuta?

Porque el range() está vacío o mal definido.

2. ¿Por qué mi bucle parece infinito?

Un for nunca es infinito. El problema está dentro del bloque.

3. TypeError: 'int' object is not iterable

Intentas iterar un número. Usa range() o una lista.

4. ¿Por qué mi variable no cambia dentro del for?

Porque modificas la variable del bucle en vez de un acumulador externo.

5. ¿Cómo recorro dos listas a la vez?

Con zip(): for a, b in zip(lista1, lista2):





Bucle for en Python: qué es, cómo funciona y ejemplos prácticos

📘 Definición
🟢 Ejemplo básico
🔵 Ejemplo avanzado
🧩 Usos del for

¿Qué es el bucle for en Python?

El bucle for en Python permite recorrer los elementos de una secuencia —listas, cadenas, tuplas, diccionarios o rangos— ejecutando un bloque de código por cada elemento.

Funciona como un cursor que avanza por una fila de objetos: toma uno, lo asigna a la variable del ciclo y ejecuta tus instrucciones. Cuando ya no quedan elementos, el bucle termina.

Ejemplo básico


# Imprimir los números del 1 al 5
for numero in range(1, 6):
    print(numero)
        

Este bucle recorre los números del 1 al 5 e imprime cada uno.

Ejemplo avanzado


# Recorrer una lista de diccionarios y mostrar información formateada
usuarios = [
    {"nombre": "Ana", "edad": 28},
    {"nombre": "Luis", "edad": 34},
    {"nombre": "Marta", "edad": 22}
]

for usuario in usuarios:
    print(f"Nombre: {usuario['nombre']} - Edad: {usuario['edad']}")
        

Este bucle recorre una lista de diccionarios y muestra la información de cada usuario.

Usos comunes del bucle for

Uso Descripción Ejemplo
📋Recorrer una lista Itera sobre cada elemento de una lista. for x in [1,2,3]: print(x)
🔤Recorrer una cadena Procesa cada carácter de un texto. for letra in "Python": print(letra)
🔢Usar range() Genera secuencias numéricas. for i in range(5): print(i)
🗂️Recorrer diccionarios Itera claves, valores o ambos. for k,v in dic.items(): print(k,v)
📦Bucles anidados Útiles para matrices o estructuras complejas. for fila in m: for x in fila: print(x)
List Comprehension Crear listas nuevas de forma compacta. [x*2 for x in range(5)]
🧮Usar enumerate() Obtener índice y valor a la vez. for i,v in enumerate(lista): print(i,v)
🔗Usar zip() Recorrer varias listas en paralelo. for a,b in zip(l1,l2): print(a,b)
🧹Filtrar elementos Crear listas filtradas con condiciones. [x for x in nums if x>10]




📘 Bucle for en Python

Definición
Ejemplo básico
Ejemplo avanzado

¿Qué es el bucle for en Python?

El bucle for en Python es una estructura de control que permite
recorrer los elementos de una secuencia —como listas, cadenas,
tuplas, diccionarios o rangos numéricos— y ejecutar un bloque de código por
cada elemento.

Puedes imaginarlo como un cursor que avanza por una fila de objetos.
En cada paso, el bucle toma un elemento, lo asigna a la variable del ciclo
y ejecuta las instrucciones que hayas definido. Cuando ya no quedan elementos
por recorrer, el bucle finaliza automáticamente.

Ejemplo básico


# Imprimir los números del 1 al 5
for numero in range(1, 6):
    print(numero)
        

En este ejemplo, el bucle recorre los números del 1 al 5 e imprime cada uno
en pantalla.

Ejemplo avanzado


# Recorrer una lista de diccionarios y mostrar información formateada
usuarios = [
    {"nombre": "Ana", "edad": 28},
    {"nombre": "Luis", "edad": 34},
    {"nombre": "Marta", "edad": 22}
]

for usuario in usuarios:
    print(f"Nombre: {usuario['nombre']} - Edad: {usuario['edad']}")
        

Aquí el bucle for recorre una lista de diccionarios.
En cada iteración accede a los datos de cada usuario y los muestra
de forma organizada.




Ejercicios con Diccionarios en Python

1. Crear un diccionario con información de un producto


producto = {
    "nombre": "Teclado mecánico",
    "precio": 59.99,
    "stock": 120,
    "categoria": "Periféricos"
}

print(producto)
    

2. Añadir y eliminar claves dinámicamente


producto = {"nombre": "Teclado", "precio": 59.99}

# Añadir clave
producto["color"] = "Negro"

# Eliminar clave
del producto["precio"]

print(producto)
    

3. Crear un diccionario por comprensión con números pares


pares = {n: n**2 for n in range(2, 21, 2)}
print(pares)
    

4. Convertir dos listas en un diccionario


claves = ["nombre", "edad", "ciudad"]
valores = ["Ana", 28, "Madrid"]

persona = dict(zip(claves, valores))
print(persona)
    

5. Recorrer un diccionario anidado e imprimir todas las claves


datos = {
    "usuario": {
        "nombre": "Carlos",
        "edad": 30
    },
    "cuenta": {
        "tipo": "premium",
        "activo": True
    }
}

def imprimir_claves(dic):
    for clave, valor in dic.items():
        print(clave)
        if isinstance(valor, dict):
            imprimir_claves(valor)

imprimir_claves(datos)
    



Diccionarios en Python

¿Qué es un diccionario?

Un diccionario en Python es una estructura de datos que almacena información en pares clave-valor. Permite acceder rápidamente a los datos usando la clave en lugar de un índice numérico.

Características

  • Es mutable (puede modificarse).
  • No permite claves duplicadas.
  • Las claves deben ser inmutables (str, int, float, tuple…).
  • Los valores pueden ser de cualquier tipo.
  • Es una colección no ordenada.

Operaciones básicas

Acceder a un valor:
    diccionario["clave"]

Añadir o modificar:
    diccionario["nueva_clave"] = valor

Eliminar:
    del diccionario["clave"]

Obtener claves, valores o pares:
    diccionario.keys()
    diccionario.values()
    diccionario.items()
        

Ejemplo

persona = {
    "nombre": "Daniel",
    "edad": 30,
    "profesion": "Desarrollador"
}
        

Comprensión de diccionarios

cuadrados = {x: x**2 for x in range(5)}
        

Métodos útiles

get(clave, defecto)
update(otro_diccionario)
pop(clave)
popitem()
setdefault(clave, valor)
        

Diccionarios anidados

usuario = {
    "id": 1,
    "perfil": {
        "nombre": "Daniel",
        "rol": "Admin",
        "preferencias": {
            "tema": "oscuro",
            "idioma": "es"
        }
    }
}
        

Conversiones

dict([("a", 1), ("b", 2)])
dict(zip(["a", "b"], [1, 2]))

import json
dic = json.loads('{"a": 1, "b": 2}')
        

Buenas prácticas

  • Usar claves descriptivas.
  • Evitar claves duplicadas.
  • Preferir .get() cuando no estás seguro de que la clave exista.
  • Usar diccionarios anidados para datos estructurados.
  • Mantener consistencia en el tipo de claves.

Errores comunes

dic["clave"]  # KeyError si no existe
No usar listas como claves
No modificar mientras se itera
        

Ejercicios

  1. Crear un diccionario con información de un producto.
  2. Añadir y eliminar claves dinámicamente.
  3. Crear un diccionario por comprensión con números pares.
  4. Convertir dos listas en un diccionario.
  5. Recorrer un diccionario anidado e imprimir todas las claves.



🖥️ Cómo ejecutar archivos .exe y .py desde Python sin bloquear tu programa

Un módulo práctico para automatizar tareas en Windows

Cuando trabajamos con Python en entornos Windows, tarde o temprano surge una necesidad muy común: lanzar programas externos desde nuestro script. Puede ser un instalador, una herramienta auxiliar, un script .py o cualquier .exe que forme parte de tu flujo de trabajo.

Python ofrece varias formas de hacerlo, pero una de las más flexibles y potentes es el uso del módulo subprocess. En este artículo exploramos un módulo real —EjecutaExe— que encapsula esta funcionalidad y permite ejecutar archivos en segundo plano, sin bloquear la ejecución del programa principal.

Vamos paso a paso.


🔧 ¿Qué hace exactamente este módulo?

El módulo define una clase llamada EjecutaExe, cuyo propósito es muy concreto:

Lanzar un archivo .exe o .py desde Python sin detener el flujo del programa.

Esto es especialmente útil cuando quieres:

  • Ejecutar varios archivos uno tras otro sin reiniciar tu script.
  • Lanzar procesos externos mientras tu programa sigue funcionando.
  • Automatizar tareas repetitivas desde una interfaz en consola.
  • Crear herramientas de administración o utilidades internas.

🧩 1. Entendiendo la base: subprocess

El corazón del módulo es el uso de:

import subprocess

Este módulo permite a Python comunicarse con programas externos como si los ejecutaras desde la terminal o desde el Explorador de Windows.

Pero la estrella del show es:

subprocess.Popen([...])

🚀 ¿Qué hace Popen?

  • Lanza el programa inmediatamente.
  • No espera a que termine.
  • Devuelve un objeto de proceso, que puedes consultar o controlar.

Esto significa que tu script no se queda congelado esperando a que el .exe termine. El proceso corre en paralelo, como un hilo independiente.

¿Qué puedes hacer con el objeto proceso?

Si no necesitas controlarlo, simplemente lo ignoras y listo.


🧵 2. ¿Qué significa “ejecutar en segundo plano”?

Cuando usas Popen, Python no se detiene. Continúa ejecutando el resto del código mientras el archivo externo hace su trabajo.

Si hubieras usado:

subprocess.run()

entonces sí tendrías que esperar a que el programa terminara antes de seguir.

Por eso Popen es ideal para automatización, utilidades y herramientas interactivas.


🧪 3. El ejemplo práctico del módulo

El módulo incluye un ejemplo muy didáctico: un bucle infinito que permite ejecutar varios archivos sin reiniciar el programa.

El usuario escribe la ruta del archivo, y Python lo lanza en segundo plano:

proceso = subprocess.Popen(["python", archivo])

Esto garantiza compatibilidad incluso si el sistema no tiene asociado .py con Python.

Luego:

  • Se espera 2 segundos para que el proceso arranque.
  • Se comprueba si sigue activo con poll().
  • Se muestra un mensaje claro al usuario.
  • Se usa system("pause") y system("cls") para mantener la consola limpia y ordenada.

Si el archivo no existe, se captura el error:

except FileNotFoundError:
    print("No se encontró el archivo. Si no está en el PATH, escribe la ruta completa.")

Una solución elegante y muy útil para principiantes.


🧱 4. La clase completa: modularidad y claridad

El módulo organiza la explicación y el ejemplo dentro de la clase EjecutaExe, lo que permite:

  • Reutilizar el código en otros proyectos.
  • Integrarlo en menús, GUIs o herramientas más grandes.
  • Mantener una estructura limpia y escalable.

Además, incluye cadenas de documentación (self.definicion y self.ejemplo) que explican paso a paso cómo funciona todo, lo cual es perfecto para fines educativos.


🎯 5. ¿Para qué puedo usar este módulo?

Las posibilidades son amplias:

  • Lanzar scripts auxiliares desde un menú principal.
  • Crear instaladores o lanzadores personalizados.
  • Automatizar tareas repetitivas en Windows.
  • Ejecutar herramientas externas desde una interfaz Tkinter.
  • Integrar procesos paralelos en proyectos más grandes.

Si trabajas con Python en Windows, este módulo es una pieza muy útil para tu caja de herramientas.


🧠 Conclusión

El módulo EjecutaExe demuestra cómo Python puede interactuar con el sistema operativo de forma sencilla y potente. Gracias a subprocess.Popen, puedes lanzar programas externos sin bloquear tu script, lo que abre la puerta a automatizaciones, utilidades y flujos de trabajo más profesionales.

Es un ejemplo perfecto de cómo un pequeño módulo bien diseñado puede resolver un problema real de forma elegante y didáctica.




🎨 Cómo hacer que tu aplicación Tkinter muestre tu propio icono en la barra de tareas (Windows)

Guía completa paso a paso


🧩 1. Entender el problema: por qué Tkinter no cambia el icono de la barra de tareas

Tkinter permite cambiar:

Pero NO controla el icono de la barra de tareas.

En Windows, ese icono depende del ejecutable que está corriendo:

Qué ejecutas Icono que aparece
python.exe Icono de Python
pythonw.exe Icono de Python
Doble clic a un .py Icono asociado a Python
Un .exe creado por ti Tu icono personalizado

Por eso, aunque cambies el icono dentro de Tkinter, la barra de tareas sigue mostrando el de Python.


🚀 2. Solución real: convertir tu script en un .exe con PyInstaller

Esta es la forma profesional y definitiva.


🛠 2.1 Instalar PyInstaller

En la terminal:

pip install pyinstaller

📦 2.2 Crear el ejecutable con tu icono

Coloca tu archivo icono.ico en la misma carpeta que tu script.

Luego ejecuta:

pyinstaller --noconsole --icon=icono.ico tu_script.py

Explicación:

  • --noconsole → evita que se abra la consola negra
  • --icon=icono.ico → icono del ejecutable
  • tu_script.py → tu programa

📁 2.3 Dónde aparece tu .exe

PyInstaller crea dos carpetas:

dist/
build/

Tu ejecutable está en:

dist/tu_script/tu_script.exe

Ese .exe ya mostrará tu icono en la barra de tareas.


🎯 3. Código Tkinter correcto para iconos

Este es el código limpio y funcional:

import tkinter as tk
from PIL import Image, ImageTk

root = tk.Tk()

# Icono .ico (para Windows)
root.iconbitmap("icono.ico")

# Icono PNG (para Tkinter)
img = Image.open("icono.png")
icon = ImageTk.PhotoImage(img)
root.iconphoto(True, icon)

root.mainloop()

🧠 4. Consejos importantes para evitar errores

mainloop() solo se llama una vez

Nunca lo pongas dos veces.

✔ Carga las imágenes después de crear root

Tkinter necesita un contexto activo.

✔ Usa .ico para el ejecutable

Windows no acepta PNG como icono del programa.


🎁 5. Bonus: estructura recomendada para proyectos Tkinter

mi_app/
│
├── icono.ico
├── icono.png
├── main.py
└── recursos/
    └── imágenes, sonidos, etc.

Y el comando:

pyinstaller --noconsole --icon=icono.ico main.py




Crea una ventana de Tkinter con varios botones.


🟦 ¿Qué hace este código?

Crea una ventana de Tkinter con varios botones.
Cada botón hace algo distinto: abrir una web, llamar a una clase, o cerrar la ventana.

Además, dentro de la clase MenuApp se crean todas las herramientas que usarás en tu menú (Variables, Listas, Colores, etc.).


🟦 Explicación clara del código

1. Importaciones

import tkinter as tk
import webbrowser

  • tkinter → sirve para crear ventanas y botones.
  • webbrowser → sirve para abrir páginas web.

2. Importas tus clases

from ClassMenu import Menus
from ClassVariables import Variables
...

Estas son tus clases personalizadas.
Las usarás cuando el usuario pulse un botón.


3. Creas la clase principal del menú

class MenuApp:

Esta clase contiene todo el menú.


4. Constructor __init__

def __init__(self, root):

  • root es la ventana principal.
  • Aquí configuras la ventana y creas los botones.

5. Configuración de la ventana

self.root = root
self.root.configure(bg="#1e1e1e")
self.root.title(" Programación es Python ")

  • Guardas la ventana en self.root.
  • Le pones un color de fondo.
  • Le pones un título.

6. Creas las instancias de tus clases

self.menu1 = Variables()
self.app = AppColores()
self.numerobinario = DecimalBinario()
...

Esto significa:

👉 “Voy a usar estas clases dentro del menú, así que las preparo aquí”.


7. BOTÓN 1 → Variables

boton_variables = tk.Button(
    root,
    text="VARIABLES",
    ...
    command=lambda: (
        self.menu1.variables(),
        webbrowser.open_new_tab("https://danielcaraballo.es/variables-en-python/")
    )
)
boton_variables.pack(pady=5)

¿Qué hace este botón?

  1. Llama al método variables() de tu clase Variables.
  2. Abre tu página web sobre variables.

Todo eso ocurre al pulsarlo.


8. BOTÓN 2 → f-format

boton_format = tk.Button(
    root,
    text="f- Format",
    ...
    command=lambda: webbrowser.open_new_tab("https://danielcaraballo.es/f-f-format-de-un-strings/")
)
boton_format.pack(pady=10)

Este botón solo abre una web.


9. BOTÓN 3 → Listas

boton_listas = tk.Button(
    root,
    text="Listas",
    ...
    command=lambda: webbrowser.open_new_tab("https://danielcaraballo.es/las-listas-en-python/")
)
boton_listas.pack(pady=10)

Abre tu página sobre listas.


10. BOTÓN 4 → Instalación

boton_instalacion = tk.Button(
    root,
    text="Instalación y IDE de trabajo",
    ...
    command=lambda: webbrowser.open_new_tab("https://danielcaraballo.es/lenguaje-de-programacion-python/")
)
boton_instalacion.pack(pady=10)

Abre tu página sobre instalación de Python.


11. BOTÓN 5 → Cerrar menú

boton_volver = tk.Button(
    root,
    text="Menu anterior",
    ...
    command=root.destroy
)
boton_volver.pack(pady=10)

Este botón cierra la ventana.


12. Método para iniciar el menú

@staticmethod
def iniciar_menu():
    root = tk.Tk()
    root.geometry("300x300+900+20")
    MenuApp(root)
    root.mainloop()

Esto:

  • Crea la ventana.
  • Le da tamaño y posición.
  • Crea el menú dentro de la ventana.
  • Mantiene la ventana abierta.

🟦 Resumen súper fácil

Tu código:

  • Crea una ventana.
  • Crea varios botones.
  • Cada botón abre una web o llama a una clase.
  • El último botón cierra la ventana.
  • Todo está organizado dentro de una clase llamada MenuApp.