Best way to make GUIs and Executables in Python for Windows, Mac and Linux

Typically when making a program, I want users to have a familiar experience: a single .EXE file instead of some weird scripts that requires other programs to run. There are a few different ways of accomplishing this using python,. On this page I’ll explain the simplest way I’ve found to get this result, and how to debug if you run into problems with this method.

I wrote about using pySimeplGui for making dead simple GUI interfaces for python code before, and even have a simple example project,. Check those two articles out for that aspect.

As for creating the .EXE file, there are several packages that will allow you to create executables of your python scripts. The reason to do this is that you don’t want end users to have to install python  (simplified usage of your app) or you don’t want anyone seeing the actual python code. The way they work is that they create a self-extracting zip file that has your code, all associated libraries (including DLLs), and most crucially, they have a small bootloader that is a python interpreter executable. There are several available such as cx_Freeze, bbFreeze, Py2App, Py2Exe, Pyinsaller, or you can create your own from scratch  (See a chart comparing them here).

There are some problems with these tools. Several of these are not currently updated. Some don’t allow you to create a “One File” solution, meaning they require additional folders of files, etc. which in my view isn’t a true executable experience from the user perspective.  For some reason, there’s a known issue with some of these which makes the resulting executable get incorrectly flagged as a virus by virus software. There are some ways around this however.

I’ve tried out a few of these and given my recent experience with PySimuleGui, and the features I wanted, I settled on pyinstaller.

PysimpleGUI has its own interface for pysintaller to simplify things called pysinstaller-exemaker.

For some reason, my resulting executables kept getting flagged with false virus warnings on windows. I tested in Virus Total which runs multiple virus scanners at once on your file. Sure enough, lots came back with false positives.

I found two ways to fix this problem. As with most things, there’s the easy way, and then there’s the right way.

The easy way requires specific versions of python and pyinstaller on your machine.

The other way to prevent false positive virus scans is to recompile pyinstaller’s bootloader from scratch. While I did this (and explain it below), it is non-trivial.

The Easy Way: Install Correct Versions:

The easiest way to not have the virus issue is to use the correct versions of pyhton and pyinstaller as described on a no-dead link on yuriss.com.  This Completely solved the problem and is SOOO simple!  Basically you just install the correct version of python (Version 3.7.4) from python.org. If getting the windows version, make sure it is the 64-bit version, other users seem to have had issues with the 32-bit version.

Once this is installed, you can use pip on the command line to install Pyinstaller 3.4:

 pip install pyinstaller==3.4

The Right Way: Recompiling pyinstaller’s bootloader from scratch

This may be needed for future version of python or pyinstaller. Since I already went through the headache of figuring out how to do it, I’m documenting it here.

If using a version of pyinstaller that throws the virus warnings, you can’t just go to the folder PIP installed it to and compile it there. That’d be too easy of course! (This took me a long time to figure out)… If you try to do that, it’ll fail with cryptic errors.  The reason is that the file path is too long.

To overcome this, you have to perform the following steps:

  1. Clone pyinstaller’s source to a folder in your C drive, then
  2. Rebuild the bootloaders,
  3. Install pyinstaller with pip,
  4. Overwrite your pip installation with your newly built bootloader files…

Duh, obvious right?! (omgwtfwhyisthisalwayssohard!?)

Details for the steps are below:

Step 1: Open a powershell as admin and go to C:\\

cd c:\\

Download the source of pyinstaller. This will create its own folder for pyinstall:
>pre>git clone https://github.com/pyinstaller/pyinstaller

Step 2: Cd into the bootloader’s build folder:

cd .\\PyInstaller\\bootloader\\

Then run the script to reinstall. If you get an error telling you there’s no such thing as ./waf then you are in the wrong folder.

python ./waf all

Step 3: Once this is done, you can go back to vscode or wherever and install pyinstaller from pip

pip install pyinstaller

Step 4: Then navigate to python’s site packages, and copy the newly built bootloaders into the appropriate place. NOTE: PyInstaller is case sensitive here, so be careful. We’ll first make a backup of the original bootloader folder:

 mv C:\\Users\\ALaptop\\AppData\\Roaming\\Python\\Python38\\site-packages\\PyInstaller C:\\Users\\ALaptop\\AppData\\Roaming\\Python\\Python38\\site-packages\\PyInstaller.bak

Then copy in our freshly compiled bootloader:

mv C:\\PyInstaller\\bootloader C:\\Users\\ALaptop\\AppData\\Roaming\\Python\\Python38\\site-packages\\PyInstaller

Note: Now to use pysimplegui-exemaker, you must edit your computer’s %PATH environment variable to locate pyinstall. Click the windows key on the keyboard, type “environment” and click to open the first suggestion. This window will pop up that has a button towards the bottom named “Environment Variables” that you must click. In the top window pane, find “path” or “PATH” and doubleclick that line to edit it. You’ll now be able to enter a new value. You want to add the path to where pip installs its scripts.  In my case, I pasted in the following:

 C:\\Users\\ALaptop\\AppData\\Roaming\\Python\\Python38\\Scripts

Then test it out:

python -m pysimplegui-exemaker.pysimplegui-exemaker #<--If you use pysimplegui's exemaker (NOT a typo, must exactly this way) OR

pyinstall --onefile ./myProgram.py #<-- If you just use pyinstaller directly

Tada! No more virus warnings!!!!

 

Check out my other post about how to replace the default python icon in your executable files.

Easy GUIs for Python Programs

I recently got more interested in python after some MOOC classes on AI. I hadn’t really used it much since my thesis work which allowed users to write Jython scripts to control robots in my robotics simulator.  Since then I did a little webscraping project here or there but nothing big.

There was an annoying set of issues I had with python, one of which was that I couldn’t slap together GUIs as fast as I’d like to. I admit, Java had me spoiled with the wysiwyg builders in netbeans and eclipse. I honestly would gravitate to processing if I needed an interface, but now I’ve come across a stupid-simple GUI library for python called PySimpleGUI.

Basically this is a wrapper around the tKinter library (though QT and other graphics libs are available as well).  Much of setting up a GUI is done in a few lines of code. There’s a large number of example programs and a good bit of documentation. It’s slightly annoying but also awesome that the entire doc are in one giant webpage so no matter what you want, simply ctrl+f to find it on that page. Their gihub page is very insightful as well with insightful gems of example code in the issues section.  My dude even has a youtube channel full of great tutorials and explanations. I recommend getting up to speed with it starting with this playlist.

It’s as easy as installing the library:

pip install pysimplegui

One of the key features of PySimpleGUI is its simplicity. It abstracts away many of the complexities of GUI programming, making it easy for even beginners to create visually appealing and functional GUI applications. PySimpleGUI also offers a wide range of customization options, allowing users to tailor the appearance and behavior of their GUI applications to meet their specific needs.

In addition to its simplicity and customization capabilities, PySimpleGUI is also highly portable. It is compatible with multiple operating systems, including Windows, Linux, and macOS, and can be used with both Python 2 and Python 3. This makes it an excellent choice for developing GUI applications that need to be compatible with a variety of platforms.

PySimpleGUI lays out windows in a very simple grid form that is controlled by lists.  Let’s write an example to see how this works:

Check out the code below:

This is a simple converter from inches to centimeters.  Looking at the “layout” variable you can see a list which has 3 elements.

TextOutput, TextInput, Button

This is the order the elements will appear on the main screen. If I wanted to add a second row, I could simply make this a 2D list, each row containing a new line of elements in the GUI window.  For example the following puts the “OK” button on the next line down:

layout = [ [sg.Text('Enter inches'), sg.InputText(key = 'inputValue') ] , [sg.Ok()] ]

When GUI items like buttons, etc. are activated by the user, a message is sent to the “window.read()” function. You can then run if-else statements to do different things based on which button was pressed.

Of course it can get into much more complicated territory, but since there are so many example programs doing pretty much anything you can think of in one way or another it is easy to see how this library can be applied nearly anything written in python. Examples include a “how do I” app that basically tells you how to do anything you type in the question box, games like Uno and Chess, Matplotlib for graphing, even integrating with AI programs and making desktop widgets.

I’ve written a couple apps with it now for personal and professional use and I’m hooked. Definitely give it a try!

You can use trinket.io/pygame or replit.com to edit basic programs in your browwser online, but to run this code on your own computer, I use vscode. Here’s a quick tutorial on how to get that installed and set up in 5 minutes).

Overall, PySimpleGUI is a powerful and easy-to-use Python library that enables developers to create professional-quality GUI applications with minimal effort. Its simplicity, customization options, and portability make it a great choice for a wide range of projects, from small utility programs to large-scale applications.