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.
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.
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.
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
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:
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:
src/main/python
.src/main/resources/base
.If all went well, you should now be able to use the following command to launch your app:
fbs run
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?
Creating an installer for your app is also just one command away:
fbs installer
This generates a typical Windows installer for your app:
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.
If you encounter questions or run into any problems, please open an issue here.