PyInstaller

There are several tools that can be used to package a python application. One of the best tools for packaging GUI applications, such as those powered by PyQt5, is PyInstaller. PyInstaller creates a distributable single-file application. A SFA contains all of the application’s code, auxiliary files (such as the UI files), and all of the required libraries. It’s completely self contained, so the user doesn’t need to install Python or any of the required libraries. 

 

There’s documentation online for PyQt5, but I’ll go over how to package a simple python GUI into an .exe. Links for documentation and reference can be found at the end. 

 

Pre-requisites 

  • Python  
  • pip 
  • IDLE or any IDE 

Packaging a Python Script 

Step 1: Create your Virtual Environment: 

  • Create a folder to store your files 
  • Open your terminal navigate to the folder and create a virtual environment in it 

On macOS and Linux:. 

python3 -m venv env 

On Windows: 

py -m venv env 

Step 2: Activate the environment 

On macOS and Linux: 

source env/bin/activate 

On Windows: 

.\env\Scripts\activate 

  • At this point, you’re inside your virtual environment - there should be a (venv) on your terminal line 

Step 3: Install required dependencies for the simple GUI 

(env) pip install PyQt5 

Step 4: Create new Python file in the created folder, name it main.py 

Step 5: Enter the following code into it 

import sys[Text Wrapping Break]from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow[Text Wrapping Break]from PyQt5.QtCore import Qt[Text Wrapping Break][Text Wrapping Break][Text Wrapping Break]# Subclass QMainWindow to customise your application's main window[Text Wrapping Break]class MainWindow(QMainWindow):[Text Wrapping Break][Text Wrapping Break]    def __init__(self, *args, **kwargs):[Text Wrapping Break]        super(MainWindow, self).__init__(*args, **kwargs)[Text Wrapping Break][Text Wrapping Break]        self.setWindowTitle("App")[Text Wrapping Break][Text Wrapping Break]        label = QLabel("Hello World")[Text Wrapping Break][Text Wrapping Break]        # The `Qt` namespace has a lot of attributes to customise[Text Wrapping Break]        # widgets. See: http://doc.qt.io/qt-5/qt.html[Text Wrapping Break]        label.setAlignment(Qt.AlignCenter)[Text Wrapping Break][Text Wrapping Break]        # Set the central widget of the Window. Widget will expand[Text Wrapping Break]        # to take up all the space in the window by default.[Text Wrapping Break]        self.setCentralWidget(label)[Text Wrapping Break][Text Wrapping Break]# You need one (and only one) QApplication instance per application.[Text Wrapping Break]# Pass in sys.argv to allow command line arguments for your app.[Text Wrapping Break]# If you know you won't use command line arguments QApplication([]) is fine.[Text Wrapping Break]app = QApplication(sys.argv)[Text Wrapping Break][Text Wrapping Break]window = MainWindow()[Text Wrapping Break]window.show()[Text Wrapping Break][Text Wrapping Break]# Start the event loop.[Text Wrapping Break]app.exec_()[Text Wrapping Break][Text Wrapping Break]# Your application won't reach here until you exit and the event[Text Wrapping Break]# loop has stopped. 

Step 6: Navigate back to the folder with your terminal and re-activate your virtual environment 

Step 7: When you’re in your virtual environment, install PyInstaller 

pip install PyInstaller 

Step 8: Compile 

(env) pyinstaller main.py 

You should be able to run it by double clicking the executable in the dist folder. More settings can be changed by altering the SPEC file.  

 

References: 

Full Documentation 

Using Spec Files 

Comprehensive WalkthroughÂ