Cómo crear un ejecutable EXE con icono personalizado en Python

Publicado el: 11/07/2026
Tempo de leitura: 5 minutos
Criando instalador EXE com ícone personalizado em Python

Transformar una aplicación Python en un archivo EXE facilita su uso en equipos Windows donde el destinatario no desea abrir un terminal ni instalar manualmente todas las dependencias. PyInstaller analiza el programa, reúne el intérprete, módulos y archivos necesarios, y genera una distribución ejecutable. También permite asignar un icono personalizado, ocultar la consola en aplicaciones gráficas y añadir recursos como imágenes o archivos de configuración.

Antes de comenzar, revisa cómo convertir scripts en EXE, cómo utilizar entornos virtuales, cómo crear una aplicación con Tkinter, cómo trabajar con rutas y archivos y cómo instalar bibliotecas con pip.

El manual oficial de PyInstaller documenta instalación, opciones, archivos SPEC y solución de problemas. La documentación oficial de Pillow sobre ICO explica el formato utilizado por los iconos de Windows.

Qué hace PyInstaller

PyInstaller empaqueta la aplicación y sus dependencias. El usuario final puede ejecutar el resultado sin instalar Python por separado. Sin embargo, PyInstaller no es un compilador cruzado: para crear una aplicación de Windows debes construirla en Windows. Lo mismo se aplica a macOS y Linux.

Preparar un entorno limpio

python -m venv .venv
.venv\Scripts\activate
python -m pip install --upgrade pip
python -m pip install pyinstaller

Instala dentro del entorno únicamente las dependencias necesarias para la aplicación. Un entorno lleno de paquetes no utilizados puede complicar el análisis y aumentar el tamaño final.

Probar el programa antes de empaquetar

python app.py

No uses PyInstaller para ocultar errores normales del programa. Confirma que la aplicación abre, encuentra sus recursos, maneja entradas inválidas y cierra correctamente.

Crear la primera distribución

pyinstaller app.py

El comando crea normalmente las carpetas build y dist, además de un archivo app.spec. Dentro de dist encontrarás la aplicación distribuible.

Modo de una sola carpeta

El modo predeterminado genera una carpeta con el ejecutable y las bibliotecas. Suele ser más fácil de diagnosticar y puede iniciar más rápido que un paquete de un solo archivo.

pyinstaller --name MiAplicacion app.py

Entrega toda la carpeta de dist/MiAplicacion, no solamente el EXE.

Crear un solo archivo

pyinstaller --onefile --name MiAplicacion app.py

--onefile produce un ejecutable único. Durante el inicio, el programa necesita preparar sus recursos en una ubicación temporal, por lo que puede tardar más en abrir. Prueba ambos modos antes de elegir.

Preparar el icono

Windows utiliza normalmente archivos .ico. Cambiar únicamente la extensión de un PNG no crea un icono válido. Puedes convertirlo con Pillow:

from PIL import Image

imagen = Image.open("logo.png").convert("RGBA")
imagen.save(
    "logo.ico",
    sizes=[(16, 16), (32, 32), (48, 48), (256, 256)],
)

Incluye varios tamaños para que el icono se vea correctamente en el explorador, accesos directos y ventanas.

Asignar el icono

pyinstaller --onefile --icon=logo.ico --name MiAplicacion app.py

Si Windows sigue mostrando un icono anterior, puede tratarse de la caché del sistema. Cambia temporalmente el nombre del ejecutable o prueba en otra carpeta antes de concluir que la compilación falló.

Ocultar la consola

Para una aplicación gráfica:

pyinstaller --onefile --windowed --icon=logo.ico app.py

--windowed o --noconsole evita abrir la ventana de terminal. No lo uses mientras depuras, porque perderás mensajes impresos y tracebacks. Primero crea una compilación con consola, corrige los errores y después activa el modo gráfico.

Añadir imágenes y archivos

Una aplicación puede depender de recursos externos:

pyinstaller --onefile --add-data "assets;assets" app.py

En Windows, origen y destino suelen separarse con punto y coma. Consulta la sintaxis de tu versión y sistema.

Resolver rutas dentro del paquete

from pathlib import Path
import sys


def ruta_recurso(nombre):
    if getattr(sys, "frozen", False):
        base = Path(sys._MEIPASS)
    else:
        base = Path(__file__).resolve().parent
    return base / nombre

logo = ruta_recurso("assets/logo.png")

En versiones modernas, muchas aplicaciones pueden basarse en __file__, pero el patrón debe probarse en desarrollo y empaquetado. No uses el directorio de trabajo actual como si siempre fuera la carpeta del programa.

El archivo SPEC

PyInstaller crea un archivo .spec que describe análisis, recursos y salida. Para configuraciones complejas, edítalo y construye con:

pyinstaller app.spec

Guarda el SPEC en el control de versiones cuando sea parte del proceso oficial de construcción.

Imports ocultos

Algunas bibliotecas cargan módulos dinámicamente y PyInstaller no los detecta:

pyinstaller --hidden-import=nombre_modulo app.py

No añadas imports ocultos al azar. Ejecuta el EXE desde una consola, lee el error y confirma qué módulo falta. Para paquetes complejos pueden existir hooks oficiales.

Información de versión

En Windows puedes añadir metadatos como nombre del producto, compañía y versión mediante un archivo de recursos y la opción correspondiente. Mantén la versión sincronizada con el código y con el nombre de la distribución.

Guardar datos del usuario

No escribas configuraciones junto al EXE si la aplicación está instalada en una carpeta protegida. Utiliza una ubicación adecuada del perfil del usuario. Separa recursos de solo lectura de datos modificables.

Firmar el ejecutable

Un ejecutable sin firma puede generar advertencias de reputación. La firma de código utiliza un certificado y herramientas de Windows. Firmar no convierte automáticamente el programa en seguro, pero permite verificar al editor y detectar modificaciones posteriores.

Antivirus y falsos positivos

Los ejecutables empaquetados pueden activar análisis adicionales. Evita ofuscar, descargar código inesperadamente o solicitar permisos administrativos sin necesidad. Publica hashes y distribuye desde un sitio confiable. Si existe un falso positivo, utiliza los canales de revisión del proveedor de seguridad.

Crear una construcción reproducible

python -m pip freeze > requirements-build.txt
pyinstaller --clean --noconfirm app.spec

Registra la versión de Python, PyInstaller y dependencias. Construye en un entorno limpio y automatiza el proceso cuando el proyecto crezca.

Probar en otro equipo

No basta con ejecutar el EXE en la máquina de desarrollo. Prueba en una instalación limpia de Windows con permisos normales. Revisa inicio, cierre, archivos, red, actualizaciones, escalado de pantalla y caracteres no ASCII.

Errores frecuentes

Los problemas habituales son convertir un PNG cambiando la extensión, olvidar archivos de datos, activar --windowed demasiado pronto, entregar solo una parte de la carpeta, construir para otro sistema y depender del directorio actual. También es un error asumir que --onefile siempre es la mejor opción.

Conclusión

PyInstaller permite distribuir aplicaciones Python como ejecutables de Windows y asignarles un icono profesional. Construye primero en modo de carpeta y con consola, prepara un ICO real, gestiona rutas correctamente y utiliza un archivo SPEC para proyectos complejos. La distribución solo está completa después de probar el resultado en otro equipo, documentar dependencias y aplicar prácticas de seguridad.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Uso do super em Python para resolver problemas de herança
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    Cómo usar super() en Python sin errores de herencia

    Aprende a usar super() en Python con __init__, MRO, herencia múltiple, mixins, argumentos cooperativos, pruebas y composición.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Uso de multiprocessing em Python para acelerar scripts
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    Multiprocessing en Python: usa varios núcleos correctamente

    Aprende multiprocessing en Python con Process, Pool, Queue, memoria compartida, ProcessPoolExecutor, benchmarks y buenas prácticas.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Criação de geradores eficientes usando yield em Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    yield en Python: crea generadores eficientes

    Aprende yield en Python para crear generadores, procesar archivos grandes, construir pipelines, usar yield from y reducir el consumo de

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    Decoradores en Python: guía práctica y ejemplos

    Aprende decoradores en Python con wrappers, argumentos, functools.wraps, parámetros, validación, rendimiento y buenas prácticas.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Caixas empilhadas
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    Módulos y paquetes en Python: guía completa

    Aprende módulos y paquetes en Python: imports, __init__.py, estructura de proyectos, ejecución con -m, imports relativos y errores circulares.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    logo do python com objetos abaixo do logo
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    Programación orientada a objetos en Python

    Aprende programación orientada a objetos en Python con clases, objetos, atributos, métodos, propiedades, herencia, composición y ejemplos prácticos.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026