fman build system

PyQt exe creation

Build a stand-alone executable for your PyQt application on Windows.

This page describes how you can compile an existing PyQt application to a self-contained .exe on Windows. You need Python 3. We will be using a library called fbs. Its free version supports Python 3.5 and 3.6. Later Python versions require fbs Pro.

1. Create a virtual environment

You likely already have a Python environment with dependencies such as PyQt installed. We won't use it. Instead, we will create a new virtual environment. This guarantees that we have the correct library versions and that we don't interfere with your existing setup.

Open a command prompt in your project directory and execute the following:

%LOCALAPPDATA%\Programs\Python\Python36\python -m venv venv

This is if you installed 64-bit Python 3.6 in the default location. You may have to update the path otherwise. Also note that the portable / "embeddable" version that you can download from python.org does not contain the required venv module. You need a full installation.

Execute the command:

call venv\Scripts\activate.bat

Your prompt should now have the prefix venv:

The rest of this guide assumes that the virtual environment is active, that is, that you always have the venv prefix at the beginning of your prompt.

2. Install required libraries

Type the following command:

pip install fbs PyQt5

Your app may have other dependencies of its own. Use eg. pip to install them as well.

3. Test

You will likely have a main.py script with code similar to the following:

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ...
    sys.exit(app.exec())

Test that your app still works in the virtual environment by executing the following command:

python main.py

4. Sample application

For the sake of a more concrete example, we will assume for the remainder of this guide that your PyQt application consists of two files:

  • main.py
  • image.jpg

The file main.py has the following contents:

from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QLabel

import sys

if __name__ == '__main__':
    app = QApplication([])
    window = QLabel()
    image = QPixmap('image.jpg')
    window.setPixmap(image)
    window.show()
    sys.exit(app.exec())

You can use any picture you like for image.jpg. It is shown in a window when you run the app:

5. Convert to fbs's project structure

Replace main.py with the code below. Changed lines are highlighted in bold:

from fbs_runtime.application_context.PyQt5 import ApplicationContext
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QLabel

import sys

if __name__ == '__main__':
    appctxt = ApplicationContext()
    window = QLabel()
    image = QPixmap(appctxt.get_resource('image.jpg'))
    window.setPixmap(image)
    window.show()
    sys.exit(appctxt.app.exec())

In words: We import fbs's ApplicationContext. Then, instead of creating a QApplication, we instantiate ApplicationContext. To access the image file, we use the application context's .get_resource(...) method. Finally, we call appctxt.app.exec() instead of the previous app.exec().

We also need to add some files. This is best done via the following command:

fbs startproject

You will be asked a few questions such as the name of your app. Feel free to use any values you like.

The startproject command creates a src/ folder in your current directory. Move our main.py file from above into src/main/python, overwriting the file that is already there. Also move image.jpg into the (new) folder src/main/resources/base/.

Generally, if your app consists of more files than just the two above:

  • Move all Python sources into src/main/python.
  • Move all resource files into src/main/resources/base.

If all went well, you should now be able to use the following command to launch your app:

fbs run

6. Build the .exe

After the above steps, compiling your application to a stand-alone executable should be as easy as:

fbs freeze

This creates the folder target/MyApp in your project directory, with the file MyApp.exe. You can copy the folder to any other computer to run your app there. Isn't that awesome?

7. Bonus: Create an installer

Creating an installer for your app is also just one command away:

fbs installer

This generates a typical Windows installer for your app:

8. Fine-tuning

Look through the other files in the src/ directory. There, you can customize things such as your app's icon, or the main Python module.

Troubleshooting

If you encounter questions or run into any problems, please open an issue here.