How do I run PyInstaller on Windows?
There is not much fun in creating your own desktop applications if you can't share them with other people — whether than means publishing it commercially, sharing it online or just giving it to someone you know. Sharing your apps allows other people to benefit from your hard work! Show
The good news is there are tools available to help you do just that with your Python applications which work well with apps built using PyQt6. In this tutorial we'll look at the most popular tool for packaging Python applications: PyInstaller. This tutorial is broken down into a series of steps, using PyInstaller to build first simple, and then increasingly complex PySide6 applications into distributable EXE files on Windows. You can choose to follow it through completely, or skip ahead to the examples that are most relevant to your own project. We finish off by using InstallForge to create a distributable Windows installer. You always need to compile your app on your target system. So, if you want to create a Mac .app you need to do this on a Mac, for an EXE you need to use Windows. If you're impatient, you can download the Example Installer for Windows first. RequirementsPyInstaller works out of the box with Qt for Python You can install PyInstaller using
bash
If you experience problems packaging your apps, your first step should always be to update your PyInstaller and hooks package the latest versions using bash
The hooks module contains package-specific packaging instructions for PyInstaller which is updated regularly. Install in virtual environment (optional)You can also opt to install PySide6 and PyInstaller in a virtual environment (or your applications virtual environment) to keep your environment clean. bash
Once created, activate the virtual environment by running from the command line — bash
Finally, install the required libraries. python
Getting StartedIt's a good idea to start packaging your application from the very beginning so you can confirm that packaging is still working as you develop it. This is particularly important if you add additional dependencies. If you only think about packaging at the end, it can be difficult to debug exactly where the problems are. For this example we're going to start with a simple skeleton app, which doesn't do anything interesting. Once we've got the basic packaging process working, we'll extend the application to include icons and data files. We'll confirm the build as we go along. To start with, create a new folder for your application and then add the following skeleton app in a file named python
This is a basic bare-bones application which creates a custom This should produce the following window (on Windows 11). Building a basic appNow we have our simple application skeleton in place, we can run our first build test to make sure everything is working. Open your terminal (command prompt) and navigate to the folder containing your project. You can now run the following command to run the PyInstaller build. You'll see a number of messages output, giving debug information about what PyInstaller is doing. These are useful for debugging issues in your build, but can otherwise be ignored. The output that I get for running the command on Windows 11 is shown below. bash
If you look in your
folder you'll notice you now have two new folders Below is a truncated listing of the folder content, showing the bash
The The Everything necessary to run your application will be in this folder, meaning you can take this folder and "distribute" it to someone else to run your app. You can try running your app yourself now, by running the executable file, named You may also notice a console/terminal window pop up as your application runs. We'll cover how to stop that happening shortly. In the same folder as your Python file, alongside the The Spec fileThe When we ran python
The first thing to notice is that this is a Python file, meaning you can edit it and use Python code to calculate values for the settings. This is mostly useful for complex builds, for example when you are targeting different platforms and want to conditionally define additional libraries or dependencies to bundle. If you generate a Once a The
resulting build will be identical to the build used to generate the Tweaking the buildSo far we've created a simple first build of a very basic application. Now we'll look at a few of the most useful options that PyInstaller provides to tweak our build. Then we'll go on to look at building more complex applications. Naming your appOne of the simplest changes you can make is to provide a proper "name" for your application. By default the app takes the name of your source file (minus the extension), for example You can provide a nicer name for PyInstaller to use for the executable (and python
Alternatively, you can re-run the bash
The resulting EXE file will be given the name The name of the Hiding the console windowWhen you run your packaged application you will notice that a console window runs in the background. If you try and close this console window your application will also close. You almost never want this window in a GUI application and PyInstaller provides a simple way to turn this off. You can fix this in one of two ways. Firstly, you can edit the previously created python
Alternatively, you can re-run the bash
There is no difference between any of the options. Re-running One File BuildOn Windows PyInstaller has the ability to create a one-file build, that is, a single EXE file which contains all your code, libraries and data files in one. This can be a convenient way to share simple applications, as you don't need to provide an installer or zip up a folder of files. To specify a one-file
build provide the bash
Note that while the one-file build is easier to distribute, it is slower to execute than a normally built application. This is because every time the application is run it must create a temporary folder to unpack the contents of the executable. Whether this trade-off is worth the convenience for your app is up to you! Using the Since debugging a one file app is much harder, you should make sure everything is working with a normal build before you create a one-file package. We're going to continue this tutorial with a folder-based build for clarity. Setting an application IconBy default PyInstaller EXE files come with the following icon in place. You
will probably want to customize this to make your application more recognisable. This can be done easily using the bash
The portable version of IcoFx is a good free tool to create icons on Windows. Or, by adding the
python
If you now re-run the build (by using the command line arguments, or running with your modified However, if you run your application, you're going to be disappointed. The specified icon is not showing up on the window, and it will also not appear on your taskbar. Why
not? Because the icon used for the window isn't determined by the icons in the executable file, but by the application itself. To show an icon on our window we need to modify our simple application a little bit, to add a call to python
Here we've added the If you run the above application you should now see the icon appears on the window. Even if you don't see the icons, keep reading! Dealing with relative pathsThere is a gotcha here, which might not be immediately apparent. To demonstrate it, open up a shell and change to the folder where our script is located. Run it with If the icons are in the correct location, you should see them. Now change to the parent folder, and try and run your script again (change bash
The icons don't appear. What's happening? We're using relative paths to refer to our data files. These paths are relative to the current working directory -- not the folder your script is in. So if you run the script from elsewhere it won't be able to find the files. One common reason for icons not to show up, is running examples in an IDE which uses the project root as the current working directory. This is a minor issue before the app is packaged, but once it's installed you don't know what the current working directory will be when it is run -- if it's wrong your app won't be able to find anything. We need to fix this before we go any further, which we can do by making our paths relative to our application folder. In the updated code below, we define a new variable Since our python
Try and run your app again from the parent folder -- you'll find that the icon now appear as expected, no matter where you launch the app from. Taskbar IconsUnfortunately, even if the icon is showing on the window, it may still not show on the taskbar. If it does for you, great! But it may not work when you distribute your application, so it's probably a good idea to follow the next steps anyway. The final tweak we need to make to get the icon showing on the taskbar is to add some cryptic incantations to the top of our Python file. When you run your application, Windows looks at the executable and tries to guess what "application group" it belongs to. By default, any Python scripts (including your application) are grouped under the same "Python" group, and so will show the Python icon. To stop this happening, we need to provide Windows with a different application identifier. The code below does this, by calling python
The listing above shows a generic With this added to your script, running it should now show the icon on your window and taskbar. The final step is to ensure that this icon is correctly packaged with your application and continues to be shown when run from the Try it, it wont. The issue is that our application now has a dependency on a external data file (the icon file) that's not part of our source. For our application to work, we now need to distribute this data file along with it. PyInstaller can do this for us, but we need to tell it what we want to include, and where to put it in the output. In the next section we'll look at the options available to you for managing data files associated with your app. Over 10,000 developers have bought Create GUI Applications with Python & Qt! To support developers in [[ countryRegion ]] I give a [[ localizedDiscount[couponCode] ]]% discount with the code [[ couponCode ]] — Enjoy! For [[ activeDiscount.description ]] I'm giving a [[ activeDiscount.discount ]]% discount with the code [[ couponCode ]] — Enjoy! Data files and ResourcesSo far we successfully built a simple app which had no external dependencies. However, once we needed to load an external file (in this case an icon) we hit upon a problem. The file wasn't copied into our In this section we'll look at the options we have to be able to bundle external resources, such as icons or Qt
Designer Bundling data files with PyInstallerThe simplest way to get these data files into the As with other options, this can be specified by command line arguments, bash
You can provide `--add-data` multiple times. Note that the path separator is platform-specific, on Windows use `;` while on Linux or Mac use `:` Or via the python
And then execute the In both cases we are telling PyInstaller to copy the specified file If you run the build, you should see your If you run your app from The file must be loaded in Qt using a relative path, and be in the same relative location to the EXE as it was to the If your icon looks blurry it means you don't have large-enough
icon variations in your The main advantage of using PyInstaller to bundle your files in this way is you can use Python in your Bundling data foldersUsually you will have more than one data file you want to include with your packaged file. The latest PyInstaller versions let you bundle folders just like you would files, keeping the sub-folder structure. For example, lets extend our app to add some additional icons, and put them under a folder. python
The icons (PNG files and an ICO file for the Windows file icon) are stored under a subfolder named 'icons'. bash
If you run this you'll see the following window, with a Window icon and a button icon. The paths are using the Unix
forward-slash To copy the python
If you run the build using
this spec file you'll see the Alternatively, you can bundle your data files using Qt's QResource architecture. See our tutorial for more information. Building a Windows Installer with InstallForgeSo far we've used PyInstaller to bundle applications for distribution, along with the associated data files. The output of this bundling process is a folder, named While you could share this folder with your users as a ZIP file it's not the best user experience. Desktop applications are normally distributed with installers which handle the process of putting the executable (and any other files) in the correct place, adding Start Menu shortcuts and the like. Now we've successfully bundled our application, we'll next look at how we can take our Making sure the build is ready.If you've followed the tutorial so
far, you'll already have your app ready in the This packages everything up ready to distribute in the The Creating an installerNow we've successfully bundled our application, we'll next look at how we can take our To create our installer we'll be using a tool called InstallForge. InstallForge is free and you can download the installer from this page. We'll now walk through the basic steps of creating an installer with InstallForge. If you're impatient, you can download the finished Installforge Installer here. GeneralWhen you first run InstallForge you'll be presented with this General tab. Here you can enter the basic information about your application, including the name, program version, company and website. You can also select the target platforms for the installer, from various versions of Windows that are available. For desktop applications you currently probably only want to target Windows 7, 8 and 10. SetupClick on the left sidebar to open the "Files" page under "Setup". Here you can specify the files to be bundled in the installer. Use "Add Files…" and select all the files in the Once you're finished scroll through the list to the bottom and ensure that the folders are listed to be included. You want all files and folders under The default install path can be left as-is. The values between angled brackets, e.g. Next, it's nice to allow your users to uninstall your application. Even though it's undoubtedly awesome, they may want to remove it at some time in the future. You can do this under the "Uninstall" tab, simply by ticking the box. This will also make the application appear in "Add or Remove Programs". DialogsThe "Dialogs" section can be used to show custom messages, splash screens or license information to the user. The "Finish" tab lets you control what happens once the installer is complete, and it's helpful here to give the user the option to run your program. To do this you need to tick the box next to "Run program" and add your own application EXE into the box. Since SystemUnder "System" select "Shortcuts" to open the shortcut editor. Here you can specify shortcuts for both the Start Menu and Desktop if you like. Click "Add…" to add new shortcuts
for your application. Choose between Start menu and Desktop shortcuts, and fill in the name and target file. This is the path your application EXE will end up at once installed. Since BuildWith the basic settings in place, you can now build your installer. At this point you can save your InstallForge project so you can re-build the installer from the same settings in future. Click on the "Build" section at the bottom to open the build panel. Click on the large icon button to start the build process. If you haven't already specified a setup file location you will be prompted for one. This is the location where you want the completed installer to be saved. Don't save it in
your The build process will began, collecting and compressing the files into the installer. Once complete you will be prompted to run the installer. This is entirely optional, but a handy way to find out if it works. Running the installerThe installer itself shouldn't have any surprises, working as expected. Depending on the options selected in InstallForge you may have extra panels or options. Step through the installer until it is complete. You can optionally run the application from the last page of the installer, or you can find it in your start menu. Wrapping upIn this tutorial we've covered how to build your PySide6 applications into a distributable EXE using PyInstaller, including adding data files along with your code. Then we walked through the process of building the application into a Windows Installer using InstallForge. Following these steps you should be able to package up your own applications and make them available to other people. For a complete view of all PyInstaller bundling options take a look at the PyInstaller usage documentation. Does PyInstaller work on Windows?PyInstaller supports making executables for Windows, Linux, and macOS, but it cannot cross compile.
Can you run a PyInstaller exe without Python?They do not need to have Python installed at all. The output of PyInstaller is specific to the active operating system and the active version of Python.
Where is PyInstaller exe located in Windows?After installation, the pyinstaller binary is located in your virtual environment's bin/ directory, or where your Python executable is located. If that directory isn't in your PATH , include the whole path when you run pyinstaller .
Why is PyInstaller exe not working?The most common reason a PyInstaller package fails is that PyInstaller failed to bundle a required file. Such missing files fall into a few categories: Hidden or missing imports: Sometimes PyInstaller can't detect the import of a package or library, typically because it is imported dynamically.
|