Technical Note: Distribuzione e Desktop Launcher per Binari PyInstaller

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:

  1. Spostare il launcher:
    mv ~/Desktop/PyInstallerGUIWrapper.desktop ~/.local/share/applications/
    
  2. 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 Path nel file .desktop non 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

  1. Binario: Deve essere eseguibile (chmod +x).
  2. File .desktop: Percorsi assoluti obbligatori in Exec e Path.
  3. Trust: gio set ... metadata::trusted true per icone sul desktop.
  4. 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:

  1. Selezione File: Apre una finestra per selezionare il binario eseguibile.
  2. Selezione Icona: Chiede facoltativamente di selezionare un’immagine per l’icona.
  3. Generazione: Crea il file .desktop con i percorsi assoluti corretti.
  4. Permessi: Imposta il bit di esecuzione (chmod +x).
  5. Trust: Utilizza gio per 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

  1. Requisiti: Assicurati di avere python3-tk installato (necessario per le finestre di selezione su Linux):
    sudo apt install python3-tk
    
  2. Esecuzione:
    python3 desktop_launcher_creator.py
    
  3. Procedura:
    • Si aprirà una finestra: seleziona il tuo file eseguibile (es. quello nella cartella dist di 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.

Perché usare questo script?

  • Gestione del Path: Lo script identifica automaticamente la working directory (il campo Path del 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.
Last updated on Sunday, February 15, 2026
Built with Hugo
Theme Stack designed by Jimmy