feat: Implement main application GUI with tabbed interface, add seed database, and enhance image path resolution.
This commit is contained in:
Binary file not shown.
@@ -197,6 +197,21 @@ class MainWindow:
|
|||||||
fg=TEXT_MUTED
|
fg=TEXT_MUTED
|
||||||
).pack(side=tk.RIGHT)
|
).pack(side=tk.RIGHT)
|
||||||
|
|
||||||
|
# Diagnostics Button
|
||||||
|
diag_btn = tk.Button(
|
||||||
|
status_frame,
|
||||||
|
text="🔍 Diagnostics",
|
||||||
|
font=FONT_SMALL,
|
||||||
|
bg=BG_MEDIUM,
|
||||||
|
fg=ACCENT_TERTIARY,
|
||||||
|
bd=0,
|
||||||
|
activebackground=BG_LIGHT,
|
||||||
|
activeforeground=TEXT_PRIMARY,
|
||||||
|
cursor='hand2',
|
||||||
|
command=self.show_diagnostics
|
||||||
|
)
|
||||||
|
diag_btn.pack(side=tk.RIGHT, padx=15)
|
||||||
|
|
||||||
tk.Label(
|
tk.Label(
|
||||||
status_frame,
|
status_frame,
|
||||||
text="Made by Kiyreload │ ",
|
text="Made by Kiyreload │ ",
|
||||||
@@ -240,6 +255,64 @@ class MainWindow:
|
|||||||
"""Show the update dialog"""
|
"""Show the update dialog"""
|
||||||
show_update_dialog(self.root)
|
show_update_dialog(self.root)
|
||||||
|
|
||||||
|
def show_diagnostics(self):
|
||||||
|
"""Show diagnostics information for debugging"""
|
||||||
|
diag_win = tk.Toplevel(self.root)
|
||||||
|
diag_win.title("System Diagnostics")
|
||||||
|
diag_win.geometry("700x500")
|
||||||
|
diag_win.configure(bg=BG_DARK)
|
||||||
|
|
||||||
|
from db.db_queries import DB_PATH
|
||||||
|
import platform
|
||||||
|
|
||||||
|
# Info text
|
||||||
|
info = [
|
||||||
|
f"--- Application Info ---",
|
||||||
|
f"Version: {VERSION}",
|
||||||
|
f"Frozen (EXE): {getattr(sys, 'frozen', False)}",
|
||||||
|
f"Python: {sys.version}",
|
||||||
|
f"Platform: {platform.platform()}",
|
||||||
|
"",
|
||||||
|
f"--- Database ---",
|
||||||
|
f"DB Path: {DB_PATH}",
|
||||||
|
f"DB Exists: {os.path.exists(DB_PATH)}",
|
||||||
|
"",
|
||||||
|
f"--- Search Paths ---",
|
||||||
|
f"Executable: {sys.executable}",
|
||||||
|
f"Script Root: {os.path.dirname(os.path.abspath(__file__))}",
|
||||||
|
f"MEIPASS (Temp): {getattr(sys, '_MEIPASS', 'N/A')}",
|
||||||
|
"",
|
||||||
|
f"--- Image Check ---"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Check some images
|
||||||
|
img_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'images')
|
||||||
|
info.append(f"Images Dir (Source): {img_dir}")
|
||||||
|
info.append(f"Exists: {os.path.exists(img_dir)}")
|
||||||
|
|
||||||
|
if os.path.exists(img_dir):
|
||||||
|
files = os.listdir(img_dir)
|
||||||
|
info.append(f"Files found: {len(files)}")
|
||||||
|
if len(files) > 0:
|
||||||
|
info.append(f"Sample: {files[0]}")
|
||||||
|
|
||||||
|
content = "\n".join(info)
|
||||||
|
|
||||||
|
# Display area
|
||||||
|
text_frame = tk.Frame(diag_win, bg=BG_DARK, padx=20, pady=20)
|
||||||
|
text_frame.pack(fill=tk.BOTH, expand=True)
|
||||||
|
|
||||||
|
from gui.theme import create_styled_text
|
||||||
|
text_area = create_styled_text(text_frame)
|
||||||
|
text_area.pack(fill=tk.BOTH, expand=True)
|
||||||
|
text_area.insert(tk.END, content)
|
||||||
|
text_area.config(state=tk.DISABLED)
|
||||||
|
|
||||||
|
# Close button
|
||||||
|
btn_frame = tk.Frame(diag_win, bg=BG_DARK, pady=15)
|
||||||
|
btn_frame.pack(fill=tk.X)
|
||||||
|
create_styled_button(btn_frame, text="Close", command=diag_win.destroy).pack()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""
|
"""
|
||||||
Start the GUI application and display the main window.
|
Start the GUI application and display the main window.
|
||||||
|
|||||||
48
utils.py
48
utils.py
@@ -6,23 +6,45 @@ def resolve_image_path(db_path):
|
|||||||
"""
|
"""
|
||||||
Resolve the absolute path to an image file.
|
Resolve the absolute path to an image file.
|
||||||
Handles the case where the database contains paths from a different machine/drive.
|
Handles the case where the database contains paths from a different machine/drive.
|
||||||
Also handles frozen (PyInstaller) state.
|
Searches multiple locations:
|
||||||
|
1. Bundled resources (_MEIPASS for PyInstaller)
|
||||||
|
2. Local 'images' folder next to the .exe or project root
|
||||||
|
3. The directory containing the source files
|
||||||
"""
|
"""
|
||||||
if not db_path:
|
if not db_path:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
filename = os.path.basename(db_path)
|
filename = os.path.basename(db_path)
|
||||||
|
|
||||||
# Check if running as frozen executable
|
# List of directories to search
|
||||||
if getattr(sys, 'frozen', False):
|
search_dirs = []
|
||||||
# PyInstaller creates a temp folder and stores path in _MEIPASS
|
|
||||||
if hasattr(sys, '_MEIPASS'):
|
|
||||||
root_dir = sys._MEIPASS
|
|
||||||
else:
|
|
||||||
root_dir = os.path.dirname(sys.executable)
|
|
||||||
else:
|
|
||||||
# Get the project root directory (directory where this utils.py resides)
|
|
||||||
root_dir = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
|
|
||||||
# Construct optimal path
|
# 1. Check if running as frozen executable
|
||||||
return os.path.join(root_dir, 'images', filename)
|
if getattr(sys, 'frozen', False):
|
||||||
|
if hasattr(sys, '_MEIPASS'):
|
||||||
|
# Bundled images folder in _MEIPASS
|
||||||
|
search_dirs.append(os.path.join(sys._MEIPASS, 'images'))
|
||||||
|
|
||||||
|
# Folder next to the .exe
|
||||||
|
exe_dir = os.path.dirname(sys.executable)
|
||||||
|
search_dirs.append(os.path.join(exe_dir, 'images'))
|
||||||
|
search_dirs.append(exe_dir) # Maybe images are flat in exe dir
|
||||||
|
|
||||||
|
# 2. Source code directory
|
||||||
|
source_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
search_dirs.append(os.path.join(source_dir, 'images'))
|
||||||
|
|
||||||
|
# 3. Parent of source code (project root)
|
||||||
|
project_root = os.path.dirname(source_dir)
|
||||||
|
search_dirs.append(os.path.join(project_root, 'images'))
|
||||||
|
|
||||||
|
# Try each search directory
|
||||||
|
for d in search_dirs:
|
||||||
|
if not d: continue
|
||||||
|
test_path = os.path.join(d, filename)
|
||||||
|
if os.path.exists(test_path):
|
||||||
|
return test_path
|
||||||
|
|
||||||
|
# Fallback: if we haven't found it, return what would be the standard local path
|
||||||
|
# even if it doesn't exist (helpful for debugging)
|
||||||
|
return os.path.join(source_dir, 'images', filename)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ This file is the single source of truth for the application version.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Semantic versioning: MAJOR.MINOR.PATCH
|
# Semantic versioning: MAJOR.MINOR.PATCH
|
||||||
VERSION: str = "13.0.2"
|
VERSION: str = "13.0.3"
|
||||||
|
|
||||||
# Application metadata
|
# Application metadata
|
||||||
APP_NAME: str = "UmamusumeCardManager"
|
APP_NAME: str = "UmamusumeCardManager"
|
||||||
|
|||||||
Reference in New Issue
Block a user