Init build

This commit is contained in:
SpaceNerd0717
2025-10-15 01:06:18 -04:00
parent d1fef202ad
commit 6a5f069255
20 changed files with 26804 additions and 21 deletions

4015
build/main/Analysis-00.toc Normal file

File diff suppressed because it is too large Load Diff

2966
build/main/EXE-00.toc Normal file

File diff suppressed because it is too large Load Diff

2944
build/main/PKG-00.toc Normal file

File diff suppressed because it is too large Load Diff

BIN
build/main/PYZ-00.pyz Normal file

Binary file not shown.

1084
build/main/PYZ-00.toc Normal file

File diff suppressed because it is too large Load Diff

BIN
build/main/base_library.zip Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
build/main/main.pkg Normal file

Binary file not shown.

46
build/main/warn-main.txt Normal file
View File

@@ -0,0 +1,46 @@
This file lists modules PyInstaller was not able to find. This does not
necessarily mean this module is required for running your program. Python and
Python 3rd-party packages include a lot of conditional or optional modules. For
example the module 'ntpath' only exists on Windows, whereas the module
'posixpath' only exists on Posix systems.
Types if import:
* top-level: imported at the top-level - look at these first
* conditional: imported within an if-statement
* delayed: imported within a function
* optional: imported within a try-except-statement
IMPORTANT: Do NOT post this list to the issue-tracker. Use it as a basis for
tracking down the missing module yourself. Thanks!
missing module named pwd - imported by shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional), posixpath (delayed, conditional, optional), netrc (delayed, conditional), getpass (delayed)
missing module named grp - imported by shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional)
missing module named _posixsubprocess - imported by subprocess (conditional), multiprocessing.util (delayed)
missing module named fcntl - imported by subprocess (optional)
missing module named _posixshmem - imported by multiprocessing.resource_tracker (conditional), multiprocessing.shared_memory (conditional)
missing module named _scproxy - imported by urllib.request (conditional)
missing module named termios - imported by getpass (optional)
missing module named multiprocessing.BufferTooShort - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
missing module named multiprocessing.AuthenticationError - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional), zipimport (top-level)
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional), zipimport (top-level)
missing module named posix - imported by shutil (conditional), importlib._bootstrap_external (conditional), os (conditional, optional), posixpath (optional)
missing module named resource - imported by posix (top-level)
missing module named multiprocessing.get_context - imported by multiprocessing (top-level), multiprocessing.pool (top-level), multiprocessing.managers (top-level), multiprocessing.sharedctypes (top-level)
missing module named multiprocessing.TimeoutError - imported by multiprocessing (top-level), multiprocessing.pool (top-level)
missing module named multiprocessing.set_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
missing module named multiprocessing.get_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
missing module named pyimod02_importers - imported by C:\Users\forjn\AppData\Local\Programs\Python\Python312\Lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_pkgutil.py (delayed)
missing module named simplejson - imported by requests.compat (conditional, optional)
missing module named dummy_threading - imported by requests.cookies (optional)
missing module named asyncio.DefaultEventLoopPolicy - imported by asyncio (delayed, conditional), asyncio.events (delayed, conditional)
missing module named zstandard - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named brotlicffi - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named socks - imported by urllib3.contrib.socks (optional)
missing module named bcrypt - imported by cryptography.hazmat.primitives.serialization.ssh (optional)
missing module named cryptography.x509.UnsupportedExtension - imported by cryptography.x509 (optional), urllib3.contrib.pyopenssl (optional)
missing module named 'OpenSSL.crypto' - imported by urllib3.contrib.pyopenssl (delayed, conditional)
missing module named OpenSSL - imported by urllib3.contrib.pyopenssl (top-level)
missing module named pyodide - imported by urllib3.contrib.emscripten.fetch (top-level)
missing module named js - imported by urllib3.contrib.emscripten.fetch (top-level)

15310
build/main/xref-main.html Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,7 @@ body {
color: white; color: white;
font-family: Consolas, monospace; font-family: Consolas, monospace;
} }
#mission { font-size: 4vw; margin-bottom: 20px; } #mission { font-size: 4vw; margin-bottom: 0; }
#timer { font-size: 8vw; margin-bottom: 40px; } #timer { font-size: 8vw; margin-bottom: 40px; }
</style> </style>
<script> <script>
@@ -21,7 +21,7 @@ setTimeout(() => location.reload(), 1000);
</script> </script>
</head> </head>
<body> <body>
<div id="mission">Starship Flight 12</div> <div id="mission">Placeholder Mission</div>
<div id="timer">T-00:00:00</div> <div id="timer">T-00:00:00</div>
</body> </body>
</html> </html>

BIN
dist/installers/0.2.0/RLCInstaller.exe vendored Normal file

Binary file not shown.

243
exemaker.py Normal file
View File

@@ -0,0 +1,243 @@
#!/usr/bin/env python3
"""
Simple Tkinter GUI to run PyInstaller and make an exe from a .py file.
Features:
- choose script
- choose onefile / dir
- choose windowed (noconsole)
- add icon
- add additional data (file or folder; multiple, separated by semicolons)
- set output folder
- show live PyInstaller output
- cancel build
"""
import tkinter as tk
from tkinter import filedialog, messagebox, scrolledtext
import subprocess
import threading
import sys
import shlex
import os
from pathlib import Path
class BuilderGUI(tk.Tk):
def __init__(self):
super().__init__()
self.title("Python → EXE (PyInstaller GUI)")
self.geometry("800x600")
self.create_widgets()
self.proc = None # subprocess handle
self.stop_requested = False
def create_widgets(self):
frame_top = tk.Frame(self)
frame_top.pack(fill="x", padx=10, pady=8)
tk.Label(frame_top, text="Script:").grid(row=0, column=0, sticky="e")
self.script_entry = tk.Entry(frame_top, width=70)
self.script_entry.grid(row=0, column=1, padx=6)
tk.Button(frame_top, text="Browse...", command=self.browse_script).grid(row=0, column=2)
tk.Label(frame_top, text="Output folder:").grid(row=1, column=0, sticky="e")
self.out_entry = tk.Entry(frame_top, width=70)
self.out_entry.grid(row=1, column=1, padx=6)
tk.Button(frame_top, text="Choose...", command=self.choose_output).grid(row=1, column=2)
opts_frame = tk.LabelFrame(self, text="Options", padx=8, pady=8)
opts_frame.pack(fill="x", padx=10)
self.onefile_var = tk.BooleanVar(value=True)
tk.Checkbutton(opts_frame, text="Onefile (single exe)", variable=self.onefile_var).grid(row=0, column=0, sticky="w", padx=6, pady=2)
self.windowed_var = tk.BooleanVar(value=False)
tk.Checkbutton(opts_frame, text="Windowed (no console) / --noconsole", variable=self.windowed_var).grid(row=0, column=1, sticky="w", padx=6, pady=2)
tk.Label(opts_frame, text="Icon (.ico):").grid(row=1, column=0, sticky="e")
self.icon_entry = tk.Entry(opts_frame, width=50)
self.icon_entry.grid(row=1, column=1, sticky="w", padx=6)
tk.Button(opts_frame, text="Browse", command=self.browse_icon).grid(row=1, column=2)
tk.Label(opts_frame, text="Additional data (src;dest pairs separated by ';', e.g. resources;resources):").grid(row=2, column=0, columnspan=3, sticky="w", pady=(6,0))
self.data_entry = tk.Entry(opts_frame, width=110)
self.data_entry.grid(row=3, column=0, columnspan=3, padx=6, pady=4)
tk.Label(opts_frame, text="Extra PyInstaller args:").grid(row=4, column=0, sticky="w")
self.extra_entry = tk.Entry(opts_frame, width=80)
self.extra_entry.grid(row=4, column=1, columnspan=2, padx=6, pady=4, sticky="w")
run_frame = tk.Frame(self)
run_frame.pack(fill="x", padx=10, pady=8)
self.build_btn = tk.Button(run_frame, text="Build EXE", command=self.start_build, bg="#2b7a78", fg="white")
self.build_btn.pack(side="left", padx=(0,6))
self.cancel_btn = tk.Button(run_frame, text="Cancel", command=self.request_cancel, state="disabled", bg="#b00020", fg="white")
self.cancel_btn.pack(side="left")
clear_btn = tk.Button(run_frame, text="Clear Log", command=self.clear_log)
clear_btn.pack(side="left", padx=6)
open_out_btn = tk.Button(run_frame, text="Open Output Folder", command=self.open_output)
open_out_btn.pack(side="right")
self.log = scrolledtext.ScrolledText(self, height=18, font=("Consolas", 10))
self.log.pack(fill="both", expand=True, padx=10, pady=(0,10))
def browse_script(self):
path = filedialog.askopenfilename(filetypes=[("Python files", "*.py")])
if path:
self.script_entry.delete(0, tk.END)
self.script_entry.insert(0, path)
# default output to script parent /dist
parent = os.path.dirname(path)
default_out = os.path.join(parent, "dist")
self.out_entry.delete(0, tk.END)
self.out_entry.insert(0, default_out)
def choose_output(self):
path = filedialog.askdirectory()
if path:
self.out_entry.delete(0, tk.END)
self.out_entry.insert(0, path)
def browse_icon(self):
path = filedialog.askopenfilename(filetypes=[("Icon files", "*.ico")])
if path:
self.icon_entry.delete(0, tk.END)
self.icon_entry.insert(0, path)
def clear_log(self):
self.log.delete("1.0", tk.END)
def open_output(self):
out = self.out_entry.get().strip()
if not out:
messagebox.showinfo("Output folder", "No output folder set.")
return
os.startfile(out) if os.name == "nt" else subprocess.run(["xdg-open", out])
def request_cancel(self):
if self.proc and self.proc.poll() is None:
self.stop_requested = True
# try terminate politely
try:
self.proc.terminate()
except Exception:
pass
self.log_insert("\nCancellation requested...\n")
self.cancel_btn.config(state="disabled")
def log_insert(self, text):
self.log.insert(tk.END, text)
self.log.see(tk.END)
def start_build(self):
script = self.script_entry.get().strip()
if not script or not os.path.isfile(script):
messagebox.showerror("Error", "Please choose a valid Python script to build.")
return
out_dir = self.out_entry.get().strip() or os.path.dirname(script)
os.makedirs(out_dir, exist_ok=True)
self.build_btn.config(state="disabled")
self.cancel_btn.config(state="normal")
self.stop_requested = False
self.clear_log()
# Start build on a thread to keep UI responsive
thread = threading.Thread(target=self.run_pyinstaller, args=(script, out_dir), daemon=True)
thread.start()
def run_pyinstaller(self, script, out_dir):
# Build the PyInstaller command
cmd = [sys.executable, "-m", "PyInstaller"]
if self.onefile_var.get():
cmd.append("--onefile")
else:
cmd.append("--onedir")
if self.windowed_var.get():
cmd.append("--noconsole")
icon = self.icon_entry.get().strip()
if icon:
cmd.extend(["--icon", icon])
# add additional data: user can provide pairs like "data;data" or "assets;assets"
data_spec = self.data_entry.get().strip()
if data_spec:
# support multiple separated by semicolons or vertical bars
pairs = [p for p in (data_spec.split(";") + data_spec.split("|")) if p.strip()]
# normalize pairs to PyInstaller format: src;dest (on Windows use ';' in CLI but PyInstaller expects src;dest as single argument)
for p in pairs:
# if user typed "src:dest" or "src->dest", replace with semicolon
p_fixed = p.replace(":", ";").replace("->", ";")
cmd.extend(["--add-data", p_fixed])
# user extra args (raw)
extra = self.extra_entry.get().strip()
if extra:
# split carefully
cmd.extend(shlex.split(extra))
# ensure output path goes to chosen dir: use --distpath
cmd.extend(["--distpath", out_dir])
# entry script
cmd.append(script)
self.log_insert("Running PyInstaller with command:\n" + " ".join(shlex.quote(c) for c in cmd) + "\n\n")
# spawn the process
try:
self.proc = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
bufsize=1,
universal_newlines=True,
)
except Exception as e:
self.log_insert(f"Failed to start PyInstaller: {e}\n")
self.build_btn.config(state="normal")
self.cancel_btn.config(state="disabled")
return
# Stream output line by line
try:
for line in self.proc.stdout:
if line:
self.log_insert(line)
if self.stop_requested:
try:
self.proc.terminate()
except Exception:
pass
break
self.proc.wait(timeout=30)
except subprocess.TimeoutExpired:
self.log_insert("Process did not exit in time after termination.\n")
except Exception as e:
self.log_insert(f"Error while running PyInstaller: {e}\n")
retcode = self.proc.returncode if self.proc else None
if self.stop_requested:
self.log_insert("\nBuild cancelled by user.\n")
elif retcode == 0:
self.log_insert("\nBuild finished successfully.\n")
else:
self.log_insert(f"\nBuild finished with return code {retcode}.\n")
# Re-enable buttons
self.build_btn.config(state="normal")
self.cancel_btn.config(state="disabled")
self.proc = None
self.stop_requested = False
if __name__ == "__main__":
app = BuilderGUI()
app.mainloop()

View File

@@ -152,10 +152,26 @@ class CountdownApp:
frame_mode = tk.Frame(root, bg="black") frame_mode = tk.Frame(root, bg="black")
frame_mode.pack(pady=5) frame_mode.pack(pady=5)
self.mode_var = tk.StringVar(value="duration") self.mode_var = tk.StringVar(value="duration")
tk.Radiobutton(frame_mode, text="Duration", variable=self.mode_var, value="duration", self.rb_duration = tk.Radiobutton(frame_mode, text="Duration", variable=self.mode_var, value="duration",
fg="white", bg="black", command=self.update_inputs).pack(side="left", padx=5) fg="white", bg="black", indicatoron=0, width=12,
tk.Radiobutton(frame_mode, text="Clock Time", variable=self.mode_var, value="clock", command=self.update_inputs)
fg="white", bg="black", command=self.update_inputs).pack(side="left", padx=5) self.rb_duration.pack(side="left", padx=5)
self.rb_clock = tk.Radiobutton(frame_mode, text="Clock Time", variable=self.mode_var, value="clock",
fg="black", bg="white", indicatoron=0, width=12,
command=self.update_inputs)
self.rb_clock.pack(side="left", padx=5)
def update_mode_buttons(*args):
val = self.mode_var.get()
if val == 'duration':
self.rb_duration.config(bg='black', fg='white', relief='sunken')
self.rb_clock.config(bg='white', fg='black', relief='raised')
else:
self.rb_duration.config(bg='white', fg='black', relief='raised')
self.rb_clock.config(bg='black', fg='white', relief='sunken')
self.mode_var.trace_add('write', update_mode_buttons)
update_mode_buttons()
# Duration inputs # Duration inputs
frame_duration = tk.Frame(root, bg="black") frame_duration = tk.Frame(root, bg="black")

151
main.py
View File

@@ -1,5 +1,6 @@
import tkinter as tk import tkinter as tk
import time import time
import threading
from datetime import datetime from datetime import datetime
import requests import requests
import csv import csv
@@ -9,6 +10,7 @@ COUNTDOWN_HTML = "countdown.html"
GONOGO_HTML = "gonogo.html" GONOGO_HTML = "gonogo.html"
SHEET_LINK = "https://docs.google.com/spreadsheets/d/1UPJTW8vH2mgEzispjg_Y_zSqYTFaLoxuoZnqleVlSZ0/export?format=csv&gid=855477916" SHEET_LINK = "https://docs.google.com/spreadsheets/d/1UPJTW8vH2mgEzispjg_Y_zSqYTFaLoxuoZnqleVlSZ0/export?format=csv&gid=855477916"
session = requests.Session() session = requests.Session()
appVersion = "0.2.0"
# ------------------------- # -------------------------
# Fetch Go/No-Go Data # Fetch Go/No-Go Data
@@ -29,6 +31,17 @@ def fetch_gonogo():
print(f"[ERROR] Failed to fetch Go/No-Go: {e}") print(f"[ERROR] Failed to fetch Go/No-Go: {e}")
return ["ERROR"] * 3 return ["ERROR"] * 3
# -------------------------
# Helper for color
# -------------------------
def get_status_color(status):
"""Return color name for a Go/No-Go status string."""
try:
return "green" if str(status).strip().upper() == "GO" else "red"
except Exception:
return "white"
# ------------------------- # -------------------------
# Write Countdown HTML # Write Countdown HTML
# ------------------------- # -------------------------
@@ -48,7 +61,7 @@ body {{
color: white; color: white;
font-family: Consolas, monospace; font-family: Consolas, monospace;
}} }}
#mission {{ font-size: 4vw; margin-bottom: 20px; }} #mission {{ font-size: 4vw; margin-bottom: 0; }}
#timer {{ font-size: 8vw; margin-bottom: 40px; }} #timer {{ font-size: 8vw; margin-bottom: 40px; }}
</style> </style>
<script> <script>
@@ -119,9 +132,10 @@ setTimeout(() => location.reload(), 5000);
class CountdownApp: class CountdownApp:
def __init__(self, root): def __init__(self, root):
self.root = root self.root = root
self.root.title("RocketLaunchCountdown") self.root.title("RocketLaunchCountdown" + " " + appVersion)
self.root.config(bg="black") self.root.config(bg="black")
self.root.attributes("-topmost", True) self.root.attributes("-topmost", True)
self.root.geometry("800x575")
# State # State
self.running = False self.running = False
@@ -136,9 +150,13 @@ class CountdownApp:
self.gonogo_values = fetch_gonogo() self.gonogo_values = fetch_gonogo()
self.last_gonogo_update = time.time() self.last_gonogo_update = time.time()
# Title
self.titletext = tk.Label(root, text="RocketLaunchCountdown", font=("Consolas", 24), fg="white", bg="black")
self.titletext.pack(pady=(10, 0))
# Display # Display
self.text = tk.Label(root, text="T-00:00:00", font=("Consolas", 80, "bold"), fg="white", bg="black") self.text = tk.Label(root, text="T-00:00:00", font=("Consolas", 80, "bold"), fg="white", bg="black")
self.text.pack(padx=50, pady=20) self.text.pack(pady=(0, 5))
# Mission name input # Mission name input
frame_top = tk.Frame(root, bg="black") frame_top = tk.Frame(root, bg="black")
@@ -151,11 +169,32 @@ class CountdownApp:
# Mode toggle # Mode toggle
frame_mode = tk.Frame(root, bg="black") frame_mode = tk.Frame(root, bg="black")
frame_mode.pack(pady=5) frame_mode.pack(pady=5)
self.mode_var = tk.StringVar(value="duration") self.mode_var = tk.StringVar(value="duration")
tk.Radiobutton(frame_mode, text="Duration", variable=self.mode_var, value="duration",
fg="white", bg="black", command=self.update_inputs).pack(side="left", padx=5) self.radio_duration = tk.Radiobutton(
tk.Radiobutton(frame_mode, text="Clock Time", variable=self.mode_var, value="clock", frame_mode,
fg="white", bg="black", command=self.update_inputs).pack(side="left", padx=5) text="Duration",
variable=self.mode_var,
value="duration",
fg="white",
bg="black",
selectcolor="black", # makes the dot visible
command=self.update_inputs
)
self.radio_duration.pack(side="left", padx=5)
self.radio_clock = tk.Radiobutton(
frame_mode,
text="Clock Time",
variable=self.mode_var,
value="clock",
fg="white",
bg="black",
selectcolor="black", # makes the dot visible
command=self.update_inputs
)
self.radio_clock.pack(side="left", padx=5)
# Duration inputs # Duration inputs
frame_duration = tk.Frame(root, bg="black") frame_duration = tk.Frame(root, bg="black")
@@ -212,6 +251,19 @@ class CountdownApp:
self.vehicle_label = tk.Label(frame_gn, text="VEHICLE: N/A", font=("Consolas", 20), fg="white", bg="black") self.vehicle_label = tk.Label(frame_gn, text="VEHICLE: N/A", font=("Consolas", 20), fg="white", bg="black")
self.vehicle_label.pack() self.vehicle_label.pack()
# Footer
footer_frame = tk.Frame(root, bg="black")
footer_frame.pack(side="bottom", pady=0, fill="x")
self.footer_label = tk.Label(
footer_frame,
text="Made by HamsterSpaceNerd3000", # or whatever you want
font=("Consolas", 12),
fg="black",
bg="white"
)
self.footer_label.pack(fill="x")
self.update_inputs() self.update_inputs()
self.update_clock() self.update_clock()
@@ -341,9 +393,9 @@ class CountdownApp:
if now_time - self.last_gonogo_update > 0.1: if now_time - self.last_gonogo_update > 0.1:
# fetch_gonogo returns [Range, Weather, Vehicle] # fetch_gonogo returns [Range, Weather, Vehicle]
self.range_status, self.weather, self.vehicle = fetch_gonogo() self.range_status, self.weather, self.vehicle = fetch_gonogo()
self.range_label.config(text=f"RANGE: {self.range_status}") self.range_label.config(text=f"RANGE: {self.range_status}", fg=get_status_color(self.range_status))
self.weather_label.config(text=f"WEATHER: {self.weather}") self.weather_label.config(text=f"WEATHER: {self.weather}", fg=get_status_color(self.weather))
self.vehicle_label.config(text=f"VEHICLE: {self.vehicle}") self.vehicle_label.config(text=f"VEHICLE: {self.vehicle}", fg=get_status_color(self.vehicle))
self.gonogo_values = [self.range_status, self.weather, self.vehicle] self.gonogo_values = [self.range_status, self.weather, self.vehicle]
write_gonogo_html(self.gonogo_values) write_gonogo_html(self.gonogo_values)
self.last_gonogo_update = now_time self.last_gonogo_update = now_time
@@ -352,8 +404,77 @@ class CountdownApp:
if __name__ == "__main__": if __name__ == "__main__":
root = tk.Tk() # Show a small splash/loading GUI while we fetch initial data and write HTML files.
app = CountdownApp(root) def show_splash_and_start():
write_countdown_html("Placeholder Mission", "T-00:00:00") splash = tk.Tk()
write_gonogo_html(fetch_gonogo()) splash.title("RocketLaunchCountdown — Initialaization")
root.mainloop() splash.config(bg="black")
splash.geometry("400x175")
splash.attributes("-topmost", True)
title = tk.Label(splash, text="RocketLaunchCountdown", fg="white", bg="black", font=("Arial", 20, "bold"))
title.pack(pady=(10,0))
lbl = tk.Label(splash, text="Loading resources...", fg="white", bg="black", font=("Arial", 14))
lbl.pack(pady=(0,5))
info = tk.Label(splash, text="Fetching Go/No-Go and preparing HTML files.", fg="#ccc", bg="black", font=("Arial", 10))
info.pack()
cont_btn = tk.Button(splash, text="Continue", state="disabled", width=12)
cont_btn.pack(pady=8)
# Footer
footer_frame = tk.Frame(splash, bg="black")
footer_frame.pack(side="bottom", pady=0, fill="x")
footer_label = tk.Label(
footer_frame,
text="Made by HamsterSpaceNerd3000", # or whatever you want
font=("Consolas", 12),
fg="black",
bg="white"
)
footer_label.pack(fill="x")
# Shared flag to indicate initialization complete
init_state = { 'done': False, 'error': None }
def init_worker():
try:
# perform the same initial writes you had before
gonogo = fetch_gonogo()
write_countdown_html("Placeholder Mission", "T-00:00:00")
write_gonogo_html(gonogo)
init_state['done'] = True
except Exception as e:
init_state['error'] = str(e)
init_state['done'] = True
# Start background initialization
threading.Thread(target=init_worker, daemon=True).start()
def check_init():
if init_state['done']:
if init_state['error']:
info.config(text=f"Initialization error: {init_state['error']}")
else:
info.config(text="Ready. You may open browser sources now, then click Continue.")
cont_btn.config(state="normal")
splash.after(5000, on_continue)
return
splash.after(200, check_init)
def on_continue():
splash.destroy()
# now create the real main window
root = tk.Tk()
app = CountdownApp(root)
root.mainloop()
cont_btn.config(command=on_continue)
# begin polling
splash.after(100, check_init)
splash.mainloop()
show_splash_and_start()

38
main.spec Normal file
View File

@@ -0,0 +1,38 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['C:/Users/forjn/Documents/GitHub/OpenCountdown/main.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)