Distribuir tu app de Tkinter: de script de Python a programa instalable
Convierte tu prototipo de tkinter en un ejecutable listo para entregar a compañeros o clientes, mejorando mensajes, manejo de errores y aspecto visual. Incluimos una guía paso‑a‑paso con PyInstaller, comparativas de herramientas y recomendaciones de seguridad y optimización.
1. Pulir la aplicación final
Antes de empaquetar, es fundamental que la UI sea clara y que el código sea robusto. A continuación, los puntos clave:
1.1 Mejora de mensajes al usuario
- Usa
messagebox.showinfo(),showwarning()yshowerror()para comunicar estados. - Centraliza textos en un diccionario o fichero
.jsonpara facilitar la internacionalización. - Ejemplo práctico:
messages = {
"save_success": "Archivo guardado correctamente.",
"load_error": "No se pudo cargar el archivo. Verifica el formato."
}
def guardar():
try:
# lógica de guardado
messagebox.showinfo("Éxito", messages["save_success"])
except Exception as e:
messagebox.showerror("Error", f"{messages["load_error"]}\nDetalle: {e}")
1.2 Manejo estructurado de errores
Envuelve bloques críticos en try/except y registra trazas en un log rotativo.
import logging
from logging.handlers import RotatingFileHandler
logger = logging.getLogger("app")
logger.setLevel(logging.DEBUG)
handler = RotatingFileHandler("app.log", maxBytes=1_048_576, backupCount=3)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
def cargar_config():
try:
with open('config.json') as f:
return json.load(f)
except Exception as exc:
logger.exception("Error al cargar la configuración")
raise
1.3 Apariencia y consistencia visual
- Aplica un tema con
ttk.Style()(por ejemplo, "clam" o "alt"). - Define tamaños de fuente y márgenes en una hoja de estilos centralizada.
- Considera usar ttkbootstrap para obtener temas modernos de Bootstrap directamente en Tkinter.
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
app = ttk.Window(themename="darkly")
app.title("Mi aplicación")
app.geometry("600x400")
2. Generar un ejecutable con PyInstaller
PyInstaller analiza tu script, recopila dependencias y crea un bundle autónomo.
2.1 Instalación
python -m pip install --upgrade pip
pip install pyinstaller
2.2 Primer empaquetado (modo sencillo)
pyinstaller --onefile --windowed mi_app.py
Opciones clave:
--onefile: genera un único.exe(o binario en Linux/macOS).--windowed: suprime la consola en aplicaciones GUI.--icon=logo.ico: asigna un ícono propio.
2.3 Archivo .spec avanzado
Ejecuta una vez sin --onefile para que PyInstaller genere mi_app.spec. Edítalo para:
- Incluir recursos (
data_files), como imágenes o archivos de configuración. - Excluir módulos innecesarios (
excludes) y reducir el tamaño final.
# mi_app.spec – fragmento relevante
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas + [('assets/*.png', 'assets')],
strip=False,
upx=True,
name='mi_app')
2.4 Troubleshooting frecuente
| Problema | Solución rápida |
|---|---|
ImportError: _tkinter no encontrado | Instala los paquetes de desarrollo de Tk (e.g., sudo apt‑install python3‑tk en Linux) y vuelve a compilar. |
| Icono no aparece | Asegúrate de usar .ico de 256×256px y especifica --icon=app.ico antes de --onefile. |
| Ejecutable demasiado grande (>100 MB) | Activa --upx (requiere UPX) y elimina módulos no usados con la opción --exclude-module. |
| Falta archivo de configuración en tiempo de ejecución | Inclúyelo en datas del archivo .spec o empaquétalo dentro del ejecutable y recupéralo con sys._MEIPASS. |
3. Comparativa rápida de empaquetadores (máx 2 columnas)
PyInstaller
- Amplio soporte de paquetes (incluye
tkinter,PyQt5,numpy). - Genera
.speceditable para personalización. - Modo
--onefilesencillo, pero el arranque es ligeramente más lento.
Alternativas
- cx_Freeze: muy estable, pero requiere configuración manual de recursos.
- Nuitka: compila a C, produce ejecutables más rápidos y menores, aunque el proceso de compilación es más pesado.
- PyOxidizer: orientado a Rust, excelente para despliegues sin dependencias externas, aún en fase beta.
4. Compartir la aplicación con compañeros o usuarios finales
4.1 Empaquetado con instalador (Inno Setup)
Inno Setup permite crear instaladores .exe con opciones de registro, atajos y firma de código.
[Setup]
AppName=MiAppTkinter
AppVersion=1.0
DefaultDirName={pf}\MiAppTkinter
DefaultGroupName=MiAppTkinter
OutputDir=dist
OutputBaseFilename=MiApp_Installer
[Files]
Source: "dist\mi_app.exe"; DestDir: "{app}"; Flags: ignoreversion
[Icons]
Name: "{group}\MiApp"; Filename: "{app}\mi_app.exe"
4.2 Firma digital del ejecutable
En entornos corporativos, la firma evita advertencias de Windows SmartScreen.
signtool sign /f Certificado.pfx /p /tr http://timestamp.digicert.com /td sha256 /fd sha256 dist\mi_app.exe
4.3 Distribución interna
- Sube el instalador a un repositorio interno (Artifactory, Nexus) o a una carpeta compartida.
- Documenta la versión y los requisitos (Windows 10 + Python 3.9‑3.12 runtime incluido).
5. Seguridad, rendimiento y buenas prácticas
- Validación de entrada: nunca confíes en datos del usuario; usa expresiones regulares y límites de tamaño.
- Modo sandbox: si tu app abre archivos externos, restringe la ruta a directorios permitidos.
- Compresión UPX:
pyinstaller --upx-dir=C:\upxreduce el tamaño sin afectar la funcionalidad. - Pruebas automatizadas: incluye pruebas unitarias con
pytesty, si es posible, pruebas de UI conpywinautoantes del empaquetado. - Actualizaciones: considera integrar PyUpdater para ofrecer actualizaciones automáticas.
6. Siguientes pasos
Una vez que tu app está empaquetada, puedes explorar otras rutas para ampliar su alcance:
- Otras bibliotecas GUI: PyQt5/PySide6, Kivy o pywebview para interfaces más modernas.
- Migrar a aplicaciones web: usa Flask o FastAPI y sirve la UI con React o Svelte. Puedes empaquetar la web con Electron o Tauri para mantener la experiencia de escritorio.
- Contenerizar: crea una imagen Docker con
python:3.12-slimy ejecuta la app en entornos controlados (ideal para pruebas CI/CD). - Distribución en la nube: publica la lógica de negocio como microservicio (Azure Functions, AWS Lambda) y mantén la UI ligera.
Con estos pasos podrás escalar tu proyecto desde una simple herramienta de escritorio hasta una solución profesional y mantenible.
22 Distribuir tu app de Tkinter: de script de Python a programa instalable