Distribute a Python GUI App in 5 Minutes
March 15, 2025
Read on Medium- software-development
- coding
- python
- gui
- apps

In this quick guide, I will show you how to build your own Python app with a GUI using Tkinter or PyQt, and distribute it as an executable file. Currently, this approach has only been tested on Windows, but similar steps can be applied to macOS or Linux with some adjustments. I’ll update this post once I confirm those details
Create Your Python Project in a Dedicated Environment
You can create your Python project however you prefer. I tend to use PyCharm because it makes it easy to manage environments. I will also be using command prompt, PowerShell acts a bit different. After creating your project, you can set up the environment by running:
python -m venv myenv
Now activate it using:
.\myenv\Scripts\activate
Install PyInstaller and Necessary Packages
PyInstaller is one of the most popular and recommended tools for packaging Python apps into executables, which is what we’ll use in this guide. For more information, check out the documentation here.
Make sure you have activated your environment, and then install PyInstaller using:
pip install pyinstaller
For GUIs in Python, you have several options, including Tkinter and PyQt. Tkinter is already included in Python, so no installation is needed. However, I prefer using PyQt6 or PySide6, as it offers more features and a more modern aesthetic. To install PyQt6, run:
pip install PyQt6
Basic GUI Application with PyQt
Now let’s create a simple GUI application using PyQt. Create a main.py file in your project’s root directory with the following code:
# main.py
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QLabel
class GUI(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Simple PyQt6 App')
self.setGeometry(200, 200, 300, 200)
layout = QVBoxLayout()
self.label = QLabel('Hello, PyQt6!', self)
self.button = QPushButton('Click Button', self)
layout.addWidget(self.label)
layout.addWidget(self.button)
self.button.clicked.connect(self.change_text)
self.setLayout(layout)
def change_text(self):
self.label.setText("Button Clicked!")
if __name__ == '__main__':
app = QApplication(sys.argv)
window = GUI()
window.show()
sys.exit(app.exec())
Build Executable for Application
Now, let’s bundle the application into an executable using PyInstaller. Run the following command:
pyinstaller --onefile --windowed main.py
This targets the main.py file you created and will begin bundling the code, creating a build and a dist directory once completed.
- --onefile packages the code into a single executable file.
- --windowed removes the terminal window, so only the application window appears when running the .exe.
At this point, you might encounter errors with your antivirus software, marking the files as Trojan horse malware. I’ve seen this happen with Windows Defender and Bitdefender before. You have a few options:
- Temporarily disable your antivirus shield while bundling the application.
- Add an exception to your antivirus software for the path containing your project.
- You can also check the file using VirusTotal to confirm whether it’s falsely flagged.
If everything runs smoothly, you should now see a .exe file in your dist directory, which will launch your application when run.

Rebuild Using a Spec File
After bundling your application, PyInstaller will create a main.spec file that references your main.py file. The spec file allows you to customize the build process and includes instructions for how to build your application. This can be useful for adding additional files or excluding packages, for example. To rebuild the application, run:
pyinstaller main.spec
This makes it easy to rebuild your app after making changes.
Track Dependencies & Clean Up
It’s highly recommended that you add a requirements.txt file to track the dependencies in your project. You can generate the file with:
pip freeze > requirements.txt
Additionally, it’s a good idea to update your .gitignore to exclude build artifacts from your repository. Here's a sample .gitignore:
# Ignore build directories
build/
dist/
# Ignore virtual environment
.venv/
# Ignore other IDE files
.idea/
.vscode/
Conclusion
You’ve now created your own distributable GUI application in Python. PyInstaller is great at automatically bundling your code, so you likely won’t need to modify the main.spec file unless necessary. For example, I was able to package an application with an SQLite database without additional configuration.

Thanks for reading! I’m a full-stack developer specializing in React, TypeScript, and Web3 technologies.
Check out more of my work at mrmendoza.dev
Find my open-source projects on GitHub
Connect with me on LinkedIn
Let me know if this article was helpful or anything you’d like to see next.