Technical Note: Distribuzione e Desktop Launcher per Binari PyInstaller
Questa guida descrive la procedura standard per integrare un’applicazione Python compilata con PyInstaller nell’ambiente grafico di Ubuntu, permettendo l’avvio tramite icona o menu applicazioni.
1. Prerequisiti: Verifica del Binario
Prima di creare il launcher, assicurarsi che il pacchetto generato sia “self-contained” e funzioni correttamente da riga di comando.
# Sostituire con il percorso reale del binario
cd /path/to/your/dist/PyInstallerGUIWrapper/
./PyInstallerGUIWrapper
Nota: Se l’app richiede librerie di sistema (es. libxcb per Qt), il terminale mostrerà gli errori di dipendenze mancanti qui.
2. Creazione del file .desktop
Ubuntu (e i desktop GNOME/KDE) utilizza lo standard Freedesktop per i launcher. Il file deve avere estensione .desktop.
Creare il file:
nano ~/Desktop/PyInstallerGUIWrapper.desktop
Template di Configurazione (Best Practice)
Incollare il seguente contenuto, assicurandosi di usare percorsi assoluti:
[Desktop Entry]
Version=1.0
Type=Application
Name=PyInstaller GUI Wrapper
Comment=Strumento di gestione interfaccia grafica PyInstaller
# Percorso assoluto al binario eseguibile
Exec=/home/luca/Desktop/project_local/PyProject/SXXXXXXX_PyInstallerGUIWrapper/_dist/PyInstallerGUIWrapper/PyInstallerGUIWrapper
# Directory di lavoro (fondamentale per caricare asset relativi come icone o DB)
Path=/home/luca/Desktop/project_local/PyProject/SXXXXXXX_PyInstallerGUIWrapper/_dist/PyInstallerGUIWrapper
# Icona dell'applicazione (percorso assoluto a .png o .svg)
Icon=/home/luca/Desktop/project_local/PyProject/SXXXXXXX_PyInstallerGUIWrapper/resources/icon.png
Terminal=false
Categories=Development;Engineering;
StartupNotify=true
3. Autorizzazioni e Trust
Dalla versione 20.04+, Ubuntu richiede che i launcher sul Desktop siano esplicitamente marcati come “fidati”.
Passaggio 1: Permessi di esecuzione
chmod +x ~/Desktop/PyInstallerGUIWrapper.desktop
Passaggio 2: Marcatura come Trusted (via CLI)
Invece di fare click destro, è possibile automatizzare la fiducia tramite gio:
gio set ~/Desktop/PyInstallerGUIWrapper.desktop metadata::trusted true
4. Installazione di Sistema (Opzionale ma Consigliata)
Per rendere l’applicazione disponibile nel menu “Mostra Applicazioni” di Ubuntu (tasto Super), seguire questi passaggi:
- Spostare il launcher:
mv ~/Desktop/PyInstallerGUIWrapper.desktop ~/.local/share/applications/ - Aggiornare il database dei menu:
update-desktop-database ~/.local/share/applications/
5. Troubleshooting (Debug del Launcher)
Se il doppio click non avvia l’applicazione, il metodo più veloce per intercettare l’errore è utilizzare gtk-launch (che simula l’avvio grafico ma riporta gli errori nel terminale):
# Nome del file senza estensione .desktop
gtk-launch PyInstallerGUIWrapper
Errori Comuni:
- Path errato: L’applicazione non trova file di configurazione o icone perché il campo
Pathnel file.desktopnon punta alla cartella del binario. - Librerie mancanti: Se l’app crasha subito, mancano librerie dinamiche (es.
libpython3.x.so) che non sono state incluse correttamente nel bundle. - Ambiente Grafico: Se l’app richiede Wayland o X11 in modo specifico, potrebbe essere necessario aggiungere variabili d’ambiente in
Exec(es.Exec=env QT_QPA_PLATFORM=xcb ...).
Sintesi per il Sistemista
- Binario: Deve essere eseguibile (
chmod +x). - File .desktop: Percorsi assoluti obbligatori in
ExecePath. - Trust:
gio set ... metadata::trusted trueper icone sul desktop. - Menu: Spostare in
~/.local/share/applications/per integrazione totale.
Questa è un’ottima utility per velocizzare il workflow DevOps. Invece di far inserire manualmente i percorsi (spesso proni a errori di battitura), ho strutturato lo script per utilizzare una minima interfaccia grafica di selezione file (tkinter), mantenendo però la logica sistemistica per Linux.
Descrizione dello Script
Lo script esegue le seguenti operazioni:
- Selezione File: Apre una finestra per selezionare il binario eseguibile.
- Selezione Icona: Chiede facoltativamente di selezionare un’immagine per l’icona.
- Generazione: Crea il file
.desktopcon i percorsi assoluti corretti. - Permessi: Imposta il bit di esecuzione (
chmod +x). - Trust: Utilizza
gioper marcare il launcher come fidato su Ubuntu.
Python Script: desktop_launcher_creator.py
import os
import subprocess
import sys
from pathlib import Path
from tkinter import Tk, filedialog, messagebox
def create_desktop_launcher() -> None:
"""
Creates a Linux .desktop launcher for a given executable binary.
It handles path resolution, file creation, permissions, and GNOME trust.
"""
# Initialize Tkinter and hide the main window
root = Tk()
root.withdraw()
root.attributes('-topmost', True)
print("--- Desktop Launcher Creator ---")
# 1. Select the Binary file
messagebox.showinfo("Selection", "Select the executable binary file")
binary_path_raw = filedialog.askopenfilename(title="Select Executable Binary")
if not binary_path_raw:
print("Operation cancelled: No binary selected.")
return
binary_path = Path(binary_path_raw).resolve()
app_name = binary_path.stem
working_dir = binary_path.parent
# 2. Select the Icon file (Optional)
if messagebox.askyesno("Icon", "Do you want to add a custom icon?"):
icon_path_raw = filedialog.askopenfilename(
title="Select Icon File",
filetypes=[("Image files", "*.png *.svg *.ico *.jpg")]
)
icon_path = Path(icon_path_raw).resolve() if icon_path_raw else None
else:
icon_path = None
# 3. Define Desktop path
desktop_path = Path(os.path.expanduser("~/Desktop")) / f"{app_name}.desktop"
# 4. Construct the .desktop file content
desktop_entry = [
"[Desktop Entry]",
"Version=1.0",
"Type=Application",
f"Name={app_name.replace('_', ' ')}",
f"Exec={binary_path}",
f"Path={working_dir}",
"Terminal=false",
"Categories=Development;Engineering;",
"StartupNotify=true"
]
if icon_path:
desktop_entry.insert(6, f"Icon={icon_path}")
# 5. Write the file
try:
with open(desktop_path, "w", encoding="utf-8") as f:
f.write("\n".join(desktop_entry))
# 6. Set Permissions (chmod +x)
os.chmod(desktop_path, 0o755)
# 7. Set Trusted Metadata (Ubuntu specific)
subprocess.run(
["gio", "set", str(desktop_path), "metadata::trusted", "true"],
check=True
)
messagebox.showinfo("Success", f"Launcher created and trusted on Desktop:\n{desktop_path}")
print(f"Successfully created: {desktop_path}")
except Exception as e:
messagebox.showerror("Error", f"Failed to create launcher: {e}")
print(f"Error: {e}")
if __name__ == "__main__":
# Ensure we are on Linux
if not sys.platform.startswith("linux"):
print("This script is intended for Linux systems only.")
sys.exit(1)
create_desktop_launcher()
Come utilizzare lo script
- Requisiti: Assicurati di avere
python3-tkinstallato (necessario per le finestre di selezione su Linux):sudo apt install python3-tk - Esecuzione:
python3 desktop_launcher_creator.py - Procedura:
- Si aprirà una finestra: seleziona il tuo file eseguibile (es. quello nella cartella
distdi PyInstaller). - Scegli se aggiungere un’icona.
- Il file apparirà istantaneamente sul desktop, già pronto per essere cliccato senza ulteriori domande da parte del sistema operativo.
- Si aprirà una finestra: seleziona il tuo file eseguibile (es. quello nella cartella
Perché usare questo script?
- Gestione del Path: Lo script identifica automaticamente la
working directory(il campoPathdel file .desktop). Molti programmi falliscono se avviati dal desktop perché non trovano i propri file locali; questo script risolve il problema alla radice. - Automazione Trust: Il comando
gio set ... metadata::trusted trueè il “tocco segreto” che evita il fastidioso popup di Ubuntu che chiede “Vuoi lanciare questo file non fidato?”. - Zero Typos: Usando il selettore file, non c’è rischio di sbagliare a scrivere i percorsi lunghi delle home directory.