I have a Python project and I am trying to turn it into an executable using PyInstaller

My project runs with no problems in PyCharm, but when I create an executable I get this error.

Exception in Tkinter callback
Traceback (most recent call last):
File "tkinter_`_`init`_`_.py", line 1968, in `__`call`__
File "meet_systems_main.py", line 165, in open_athletes
File "subprocess.py", line 1026, in `__`init`__
File "subprocess.py", line         1538, in _execute_child
FileNotFoundError: [WinError 2] The system cannot find the file specified

video of error https://meetsystems.org/2024-09-09_17-28-23.mp4

import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
import os
import sys
import sqlite3
import subprocess



# Global variable to store the selected database file path
global_db_file_path = None

# Function to find the correct path for the image, even when bundled
def resource_path(relative_path):
    """ Get the absolute path to the resource, works for dev and PyInstaller """
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)

# Reusable function to create tables
def create_table(cursor, table_name, columns):
    """ Generic function to create a table """
    query = f"CREATE TABLE IF NOT EXISTS {table_name} ({columns})"
    cursor.execute(query)

# Function to create the SQLite database and tables
def create_database(file_path):
    conn = sqlite3.connect(file_path)
    cursor = conn.cursor()

    # Create the 'athletes' table
    create_table(cursor, 'athletes', '''
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        age INTEGER,
        team_id STRING,
        team_name STRING,
        last_name STRING,
        first_name STRING,
        middle_initials STRING,
        dob DATETIME,
        gender STRING,
        bib_number INTEGER,
        membership_number STRING
    ''')

    # Create the 'team' table
    create_table(cursor, 'teams', '''
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        team_name TEXT,
        team_code TEXT
    ''')

    # Create the 'division' table
    create_table(cursor, 'division', '''
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        division_number STRING,
        division_abbr STRING,
        division_name STRING,
        low_age INTEGER,
        high_age INTEGER,
        age_as_of_date DATETIME
    ''')

    conn.commit()
    conn.close()
    print(f"Database created successfully at: {file_path}")

# Function to open and display the tables in the selected database
def open_database():
    global global_db_file_path  # Access the global variable
    file_path = filedialog.askopenfilename(defaultextension=".db",
                                           filetypes=[("SQLite Database", "*.db")],
                                           title="Select a database to open")

    if not file_path:
        return  # User canceled the file dialog

    try:
        conn = sqlite3.connect(file_path)
        cursor = conn.cursor()

        # Query to get all table names from the SQLite master table
        cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
        tables = cursor.fetchall()

        if not tables:
            messagebox.showinfo("Info", "No tables found in the database.")
        else:
            table_names = "n".join([table[0] for table in tables])
            messagebox.showinfo("Tables in Database", f"Tables found:n{table_names}")

        conn.close()
        open_db_label.config(text=f"Opened Database: {os.path.basename(file_path)}")

        # Set the global variable with the file path
        global_db_file_path = file_path

    except sqlite3.Error as e:
        messagebox.showerror("Error", f"Failed to open the database. Error: {str(e)}")

# Function to open the 'Meet Setup' popup
def open_meet_setup():
    popup = tk.Toplevel(root)
    popup.title("Meet Setup")
    popup.geometry("300x150")

    tk.Label(popup, text="Meet Name:").pack(pady=10)
    meet_name_entry = tk.Entry(popup)
    meet_name_entry.pack(pady=10)

    def submit_meet_name():
        meet_name = meet_name_entry.get().strip()

        if not meet_name:
            messagebox.showerror("Error", "Meet Name is required")
            return

        file_path = filedialog.asksaveasfilename(defaultextension=".db",
                                                 initialfile=f"{meet_name}.db",
                                                 filetypes=[("SQLite Database", "*.db")],
                                                 title="Select location to save database")

        if file_path:
            create_database(file_path)
            popup.destroy()

    submit_button = tk.Button(popup, text="Submit", command=submit_meet_name)
    submit_button.pack(pady=10)

def open_athletes():
    if global_db_file_path:
        # Path to the Python executable in your virtual environment
        python_executable = os.path.join(os.path.dirname(sys.executable), 'python.exe')

        # Run the subprocess with the virtual environment's Python
        subprocess.Popen([python_executable, 'athletes.py', global_db_file_path])
    else:
        messagebox.showwarning("Warning", "Please open a database first.")

def open_teams():
    if global_db_file_path:
        subprocess.Popen(['python', 'teams.py', global_db_file_path])  # Pass the DB path as an argument
    else:
        messagebox.showwarning("Warning", "Please open a database first.")


# Load image from the provided file path
IMAGE_PATH = resource_path("images/britanie.png")

# Create the main application window
root = tk.Tk()
root.title("Meet Systems Meet Manager")
root.geometry("1280x720")

# Load the background image and keep a reference to avoid garbage collection
image = Image.open(IMAGE_PATH)
bg_image = ImageTk.PhotoImage(image)
root.bg_image_ref = bg_image  # Keep a reference to prevent garbage collection

# Create a label to hold the background image
bg_label = tk.Label(root, image=bg_image)
bg_label.place(x=0, y=0, relwidth=1, relheight=1)

# Create a label at the top to show which database is open
open_db_label = tk.Label(root, text="No Database Opened", font=("Helvetica", 14), bg='#ffffff', fg='#000000')
open_db_label.pack(pady=10, anchor="n")

# Add menu at the top of the window
menu_bar = tk.Menu(root)

file_menu = tk.Menu(menu_bar, tearoff=0)
file_menu.add_command(label="Meet Setup", command=open_meet_setup)
file_menu.add_command(label="Open Database", command=open_database)
file_menu.add_command(label="Division Setup")
file_menu.add_command(label="Event Setup")
file_menu.add_command(label="Athletes", command=open_athletes)
file_menu.add_command(label="Teams",command=open_teams)
file_menu.add_command(label="Seeding")
file_menu.add_command(label="Relays")

menu_bar.add_cascade(label="File", menu=file_menu)

# Add the menu to the window
root.config(menu=menu_bar)

# Add other widgets or content as needed below the menu
welcome_label = tk.Label(root, text="Meet Systems Meet Manager!", font=("Helvetica", 30), bg='#ffffff', fg='#000000')
welcome_label.pack(pady=100)

# Start the Tkinter main loop
root.mainloop()
    

    import tkinter as tk
from tkinter import ttk
from tkcalendar import Calendar
import sqlite3
import sys
import os

#db_file_path = "G:\databasetest\runners.db"
# Helper function to connect to the database
def connect_db(db_file_path):
    try:
        return sqlite3.connect(db_file_path)
    except sqlite3.Error as e:
        print(f"Failed to connect to database: {e}")
        sys.exit(1)

# Function to load athletes data into the table
def load_athletes_data(db_file_path):
    try:
        with connect_db(db_file_path) as conn:
            cursor = conn.cursor()
            cursor.execute(
                """SELECT last_name, first_name, middle_initials, gender, dob, team_id, team_name, bib_number, membership_number
                   FROM athletes;"""
            )
            athletes_data = cursor.fetchall()

            # Clear existing data
            for row in tree.get_children():
                tree.delete(row)

            # Insert data into Treeview
            for athlete in athletes_data:
                tree.insert("", "end", values=athlete)

    except sqlite3.Error as e:
        print(f"Failed to fetch data: {e}")

# Function to add a new athlete to the database
def add_athlete():
    if not validate_inputs():
        return

    athlete_data = (
        entry_last_name.get(),
        entry_first_name.get(),
        entry_mi.get(),
        entry_gender.get(),
        entry_dob.get(),
        entry_team_id.get(),
        entry_team_name.get(),
        entry_bib_number.get(),
        entry_membership_number.get(),
    )

    try:
        with connect_db(db_file_path) as conn:
            cursor = conn.cursor()

            # Check for duplicates before adding the athlete
            cursor.execute(
                "SELECT * FROM athletes WHERE LOWER(last_name) = LOWER(?) AND LOWER(first_name) = LOWER(?) AND dob = ?",
                (athlete_data[0], athlete_data[1], athlete_data[4])
            )
            if cursor.fetchone():
                print("Athlete already exists in the database.")
                return

            cursor.execute(
                """INSERT INTO athletes (last_name, first_name, middle_initials, gender, dob, team_id, team_name, bib_number, membership_number)
                   VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)""",
                athlete_data
            )
            conn.commit()

            # Clear input fields and refresh the Treeview with new data
            clear_inputs()
            load_athletes_data(db_file_path)
            print("Athlete added successfully!")

    except sqlite3.Error as e:
        print(f"Failed to add athlete: {e}")

# Function to delete a selected athlete from the database
def delete_athlete():
    selected_item = tree.selection()
    if not selected_item:
        print("Please select an athlete to delete.")
        return

    athlete = tree.item(selected_item, "values")
    last_name, first_name, dob = athlete[0], athlete[1], athlete[4]

    try:
        with connect_db(db_file_path) as conn:
            cursor = conn.cursor()
            cursor.execute(
                "DELETE FROM athletes WHERE last_name = ? AND first_name = ? AND dob = ?",
                (last_name, first_name, dob)
            )
            conn.commit()

            load_athletes_data(db_file_path)
            print("Athlete deleted successfully!")

    except sqlite3.Error as e:
        print(f"Failed to delete athlete: {e}")

# Function to update an existing athlete's data
def update_athlete():
    selected_item = tree.selection()
    if not selected_item:
        print("Please select an athlete to update.")
        return

    if not validate_inputs():
        return

    athlete_data = (
        entry_mi.get(),
        entry_gender.get(),
        entry_dob.get(),
        entry_team_id.get(),
        entry_team_name.get(),
        entry_bib_number.get(),
        entry_membership_number.get(),
        entry_last_name.get(),
        entry_first_name.get(),
        entry_dob.get(),
    )

    try:
        with connect_db(db_file_path) as conn:
            cursor = conn.cursor()
            cursor.execute(
                """UPDATE athletes SET middle_initials = ?, gender = ?, dob = ?, team_id = ?, team_name = ?, bib_number = ?, membership_number = ?
                   WHERE last_name = ? AND first_name = ? AND dob = ?""",
                athlete_data
            )
            conn.commit()

            load_athletes_data(db_file_path)
            print("Athlete updated successfully!")

    except sqlite3.Error as e:
        print(f"Failed to update athlete: {e}")

# Function to validate input fields before adding/updating an athlete
def validate_inputs():
    if not entry_last_name.get() or not entry_first_name.get() or not entry_dob.get():
        print("Last Name, First Name, and DOB are required.")
        return False
    return True

# Function to clear input fields
def clear_inputs():
    entry_last_name.delete(0, tk.END)
    entry_first_name.delete(0, tk.END)
    entry_mi.delete(0, tk.END)
    entry_gender.delete(0, tk.END)
    entry_dob.delete(0, tk.END)
    entry_team_id.delete(0, tk.END)
    entry_team_name.delete(0, tk.END)
    entry_bib_number.delete(0, tk.END)
    entry_membership_number.delete(0, tk.END)

# Function to select an athlete in the Treeview
def select_athlete(event):
    selected_item = tree.selection()
    if selected_item:
        athlete = tree.item(selected_item, "values")
        # Populate the entry fields with the selected athlete's data
        clear_inputs()
        entry_last_name.insert(0, athlete[0])
        entry_first_name.insert(0, athlete[1])
        entry_mi.insert(0, athlete[2])
        entry_gender.insert(0, athlete[3])
        entry_dob.insert(0, athlete[4])
        entry_team_id.insert(0, athlete[5])
        entry_team_name.insert(0, athlete[6])
        entry_bib_number.insert(0, athlete[7])
        entry_membership_number.insert(0, athlete[8])

# Function to open the calendar popup
def open_calendar_popup():
    def select_date():
        selected_date = cal.selection_get()
        print("Selected date:", selected_date)
        date_label.config(text=f"Selected Date: {selected_date}")

    # Create the main window
    root = tk.Tk()
    root.title("Calendar Widget")

    # Create the calendar widget
    cal = Calendar(root, selectmode='day', year=2024, month=9, day=7)
    cal.pack(pady=20)

    # Button to select date
    select_button = tk.Button(root, text="Select Date", command=select_date)
    select_button.pack(pady=10)

    # Label to display the selected date
    date_label = tk.Label(root, text="")
    date_label.pack(pady=10)

# try:
#     db_file_path = sys.argv[1] if len(sys.argv) > 1 else None
#     print(db_file_path) if db_file_path else sys.exit("No database path provided. Exiting...")
# except SystemExit as e:
#     print(e)
#     sys.exit(1)


# Check if the database path was passed as an argument
if len(sys.argv) > 1:
    db_file_path = sys.argv[1]
    print(db_file_path)
else:
    print("No database path provided. Exiting...")
    sys.exit(1)

# Create main application window
root = tk.Tk()
root.title("Athletes Table")
root.geometry("1200x600")

# Create Treeview widget
columns = ("Last Name", "First Name", "MI", "Gender", "DOB", "Team ID", "Team Name", "Bib Number", "Membership Number")
tree = ttk.Treeview(root, columns=columns, show="headings", height=10)

# Configure columns
for col in columns:
    tree.heading(col, text=col)
    tree.column(col, width=120, anchor="center")

tree.pack(pady=10, fill="both", expand=True)

# Add Scrollbars
vsb = ttk.Scrollbar(root, orient="vertical", command=tree.yview)
vsb.pack(side="right", fill="y")
tree.configure(yscrollcommand=vsb.set)

# Bind Treeview selection
tree.bind("<<TreeviewSelect>>", select_athlete)

# Input fields for adding/modifying an athlete
frame = tk.Frame(root)
frame.pack(pady=10)

tk.Label(frame, text="Last Name:").grid(row=0, column=0)
entry_last_name = tk.Entry(frame)
entry_last_name.grid(row=0, column=1)

tk.Label(frame, text="First Name:").grid(row=0, column=2)
entry_first_name = tk.Entry(frame)
entry_first_name.grid(row=0, column=3)

tk.Label(frame, text="MI:").grid(row=0, column=5)
entry_mi = tk.Entry(frame)
entry_mi.grid(row=0, column=6)

tk.Label(frame, text="Gender:").grid(row=1, column=0)
entry_gender = tk.Entry(frame)
entry_gender.grid(row=1, column=1)

# Load the calendar icon image
calendar_icon = tk.PhotoImage(file="images/file.png")

tk.Label(frame, text="DOB:").grid(row=1, column=2)
entry_dob = tk.Entry(frame)
entry_dob.grid(row=1, column=3)

# Add the button with a calendar icon next to the DOB entry
btn_calendar = tk.Button(frame, image=calendar_icon, command=open_calendar_popup)
btn_calendar.grid(row=1, column=4, padx=5)

tk.Label(frame, text="Team ID:").grid(row=1, column=5)
entry_team_id = tk.Entry(frame)
entry_team_id.grid(row=1, column=6)

tk.Label(frame, text="Team Name:").grid(row=2, column=0)
entry_team_name = tk.Entry(frame)
entry_team_name.grid(row=2, column=1)

tk.Label(frame, text="Bib Number:").grid(row=2, column=2)
entry_bib_number = tk.Entry(frame)
entry_bib_number.grid(row=2, column=3)

tk.Label(frame, text="Membership Number:").grid(row=2, column=5)
entry_membership_number = tk.Entry(frame)
entry_membership_number.grid(row=2, column=6)

# Action buttons
button_frame = tk.Frame(root)
button_frame.pack(pady=20)

btn_add = tk.Button(button_frame, text="Add Athlete", command=add_athlete)
btn_add.grid(row=0, column=0, padx=10)

btn_update = tk.Button(button_frame, text="Update Athlete", command=update_athlete)
btn_update.grid(row=0, column=1, padx=10)

btn_delete = tk.Button(button_frame, text="Delete Athlete", command=delete_athlete)
btn_delete.grid(row=0, column=2, padx=10)

btn_clear = tk.Button(button_frame, text="Clear Fields", command=clear_inputs)
btn_clear.grid(row=0, column=3, padx=10)

# Load initial data into the Treeview
load_athletes_data(db_file_path)

root.mainloop()


# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(
    ['meet_systems_main.py'],
    pathex=[],  # Add any additional paths here if needed
    binaries=[],
    datas=[
        ('images/britanie.png', 'images'),
        ('images/file.png', 'images'),
        ('athletes.py', '.')  # Ensure athletes.py is included in the build
    ],
    hiddenimports=['tkinter', 'PIL', 'sqlite3', 'tkcalendar'],  # Include all hidden imports
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)

pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.datas,
    [],
    name='meet_systems_main',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,  # Change to False if you don’t want a console window
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None
)

coll = COLLECT(
    exe,
    a.binaries,
    a.zipfiles,
    a.datas,
    strip=False,
    upx=True,
    upx_exclude=[],
    name='meet_systems_main'
)
enter image description here

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật