pip install pyinstaller
Generate the desktop App : Run PyInstaller on your Python file
pyinstaller --onefile your_script.py
PyInstaller D:\\testing\\test2.py
specifying the path to create .
pyinstaller --onefile --windowed --distpath /path/to/destination your_script.py
C:/Users/---Path here --/python3.11.exe -m PyInstaller --onefile --windowed --distpath D:\\my_app D:\\testing\\your_script.py
This option bundles your application—including the Python interpreter, your script, and all dependencies—into a single executable file. It simplifies distribution by avoiding multiple files and folders.
Also known as --noconsole
on some platforms, this flag is used for GUI applications. It prevents a console window from opening when the executable is run, ensuring a clean, user-friendly interface.
This option specifies the destination directory where the final bundled executable (or folder) will be placed. For example, using --distpath E:\my_app
directs PyInstaller to output the build in the E:\my_app
folder.
This flag allows you to include additional non-Python files (such as images, configuration files, or other data) in your bundled application. The typical syntax is:
--add-data "source_path;destination_path"
(use a semicolon ;
on Windows and a colon :
on Linux/macOS).
clock.py
: Source code or our main file. D:\\testing\\clock.py
: Full Path to our source file. D:\\my_app
: Destination path where our executable file will be stored. >pyinstaller --onefile --windowed --distpath D:\\my_app D:\\testing\\click.py
Check the table below for details of all commands used here .
calculator.py
: Source code or our main file. D:\\testing\\calculator.py
: Full Path to our source file. D:\\my_app
: Destination path where our executable file will be stored. >pyinstaller --onefile --windowed --distpath D:\\my_app D:\\testing\\calculator.py
stock_multi.py
: Source code or our main file. D:\\testing\\stock_multi.py
: Full Path to our source file. D:\\my_app
: Destination path where our executable file will be stored. >pyinstaller --onefile --windowed --distpath D:\\my_app D:\\testing\\stock_multi.py
process.py
: Source code or our main file. D:\\testing\\process.py
: Full Path to our source file. D:\\my_app
: Destination path where our executable file will be stored. >pyinstaller --onefile --windowed --distpath D:\\my_app D:\\testing\\process.py
import os
import sys
import json
from sqlalchemy import create_engine, text
# Define the JSON file's relative path
json_file = 'db_config.json'
# Check if the JSON file exists in the current working directory
if not os.path.exists(json_file):
raise FileNotFoundError(f"Configuration file {json_file} not found!")
# Load database configuration from JSON
with open(json_file, 'r') as f:
config = json.load(f)
# Establishing database connection using config
my_conn = create_engine(config['database_url']).connect()
# Rest of your Tkinter app logic
PyInstaller --onefile --windowed --distpath D:\\my_app D:\\testing\\mysql1.py
{
"database_url": "mysql+mysqldb://id:pw@localhost/my_db"
}
mysql1.py : The main source file
import tkinter as tk
import os
import sys
import json
from sqlalchemy import create_engine, text
# Define the JSON file's relative path
json_file = 'db_config.json'
# Check if the JSON file exists in the current working directory
if not os.path.exists(json_file):
raise FileNotFoundError(f"Configuration file {json_file} not found!")
# Load database configuration from JSON
with open(json_file, 'r') as f:
config = json.load(f)
# Establishing database connection using config
my_conn = create_engine(config['database_url']).connect()
r_set = my_conn.execute(text("SELECT count(*) as no from STUDENT"))
data_row = r_set.fetchone()
no_rec = data_row[0]
limit = 8
# Tkinter window setup
my_w = tk.Tk()
my_w.geometry("350x200")
def my_display(offset):
global my_conn
my_conn.close()
my_conn = create_engine(config['database_url']).connect()
q = "SELECT * from student LIMIT " + str(offset) + "," + str(limit)
r_set = my_conn.execute(text(q))
for widget in my_w.grid_slaves():
widget.grid_forget()
i = 0
for student in r_set:
for j in range(len(student)):
e = tk.Entry(my_w, width=10, fg='blue')
e.grid(row=i, column=j)
e.insert(tk.END, student[j])
i += 1
while i < limit:
for j in range(len(student)):
e = tk.Entry(my_w, width=10, fg='blue')
e.grid(row=i, column=j)
e.insert(tk.END, "")
i += 1
back = offset - limit
next = offset + limit
b1 = tk.Button(my_w, text='Next >', command=lambda: my_display(next))
b1.grid(row=12, column=4)
b2 = tk.Button(my_w, text='< Prev', command=lambda: my_display(back))
b2.grid(row=12, column=1)
if no_rec <= next:
b1["state"] = "disabled"
else:
b1["state"] = "active"
if back >= 0:
b2["state"] = "active"
else:
b2["state"] = "disabled"
my_display(0)
my_w.mainloop()
Benefits:main.py
: The main application script.db_config.json
: The JSON file containing your database connection details.import os
import sys
import json
from sqlalchemy import create_engine, text
# Check if the application is running as an executable or script
if getattr(sys, 'frozen', False):
base_dir = sys._MEIPASS # Temporary folder when running PyInstaller executable
else:
base_dir = os.path.dirname(os.path.abspath(__file__))
# Load JSON file
with open(os.path.join(base_dir, 'db_config.json'), 'r') as f:
config = json.load(f)
# Establishing database connection using config
my_conn = create_engine(config['database_url']).connect()
# Rest of your Tkinter app logic
This modification ensures that the path to the JSON file works both when running the script directly and when it's bundled into an executable by PyInstaller.
pyinstaller --onefile --add-data "db_config.json;." main.py
Explanation:Command | Description |
---|---|
pyinstaller your_script.py | Creates a bundled application from the Python script with the default settings. |
--onefile | Packages the application into a single executable file. |
--windowed | Generates an application without a console window (for GUI applications). |
--add-data "source;destination" | Adds non-Python files (like images or config files) to the bundle. |
--icon=myicon.ico | Includes a custom icon for the generated executable. |
--clean | Removes temporary files from previous builds before creating the executable. |
--name my_app_name | Sets a custom name for the output executable. |
--noconfirm | Automatically overwrites existing output files without prompting for confirmation. |