pythonpython-2.7gtkcross-platformgtk3

Creating an installer for a python GTK3 application


I have just finished developing a Python 2.7 application using Gtk3 for GUI. My question is, how can I now create an installer for Windows, Mac, and Linux (possibly three different installers) for my end-users to easily download the application without having to download python and GTK and such.

I have never created an installer from a python script before. I have heard that are some tools for this purpose (py2exe? pyinstaller?), but I wouldn't know how and what to pack with them in order for it to be able to use Gtk3.


Solution

  • After a few days of searching the internet for a solution, I have finally stumbled upon this blog-post, that helped me to create an .exe to run the program on Windows, which was my main goal.

    For future reference, these were the steps I took:


    setup.py:

    from distutils.core import setup 
    import py2exe 
    import sys, os, site, shutil
      
    site_dir = site.getsitepackages()[1] 
    include_dll_path = os.path.join(site_dir, "gnome") 
      
    gtk_dirs_to_include = ['etc', 'lib\\gtk-3.0', 'lib\\girepository-1.0', 'lib\\gio', 'lib\\gdk-pixbuf-2.0', 'share\\glib-2.0', 'share\\fonts', 'share\\icons', 'share\\themes\\Default', 'share\\themes\\HighContrast'] 
      
    gtk_dlls = [] 
    tmp_dlls = [] 
    cdir = os.getcwd() 
    for dll in os.listdir(include_dll_path): 
        if dll.lower().endswith('.dll'): 
            gtk_dlls.append(os.path.join(include_dll_path, dll)) 
            tmp_dlls.append(os.path.join(cdir, dll)) 
      
    for dll in gtk_dlls: 
        shutil.copy(dll, cdir) 
    
    # -- change main.py if needed -- #
    setup(windows=['main.py'], options={ 
        'py2exe': { 
            'includes' : ['gi'], 
            'packages': ['gi'] 
        } 
    }) 
      
    dest_dir = os.path.join(cdir, 'dist') 
    
    if not os.path.exists(dest_dir):
        os.makedirs(dest_dir)
    
    for dll in tmp_dlls: 
        shutil.copy(dll, dest_dir) 
        os.remove(dll) 
      
    for d  in gtk_dirs_to_include: 
        shutil.copytree(os.path.join(site_dir, "gnome", d), os.path.join(dest_dir, d))
    


    As far as I'm aware of this solution only work for distributing for Windows (which was my main goal), but in the future I am going to try and do the same for Linux and OSX, and I'll update the answer accordingly