Fix icon loading in PyInstaller builds
PyInstaller bundles data files into sys._MEIPASS, not the executable directory. - Add get_resource_path() helper in main.py and main_window.py - Use _MEIPASS for bundled resources (icon, web files) - Keep app_dir pointing to executable directory for user data (macros.json) This fixes the missing icon in taskbar and system tray on Windows builds. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,15 @@ import sys
|
|||||||
import threading
|
import threading
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
def get_resource_path(relative_path):
|
||||||
|
"""Get the path to a bundled resource file."""
|
||||||
|
if getattr(sys, 'frozen', False):
|
||||||
|
base_path = sys._MEIPASS
|
||||||
|
else:
|
||||||
|
base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
return os.path.join(base_path, relative_path)
|
||||||
|
|
||||||
from PySide6.QtWidgets import (
|
from PySide6.QtWidgets import (
|
||||||
QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
||||||
QLabel, QPushButton, QTabWidget, QGridLayout,
|
QLabel, QPushButton, QTabWidget, QGridLayout,
|
||||||
@@ -293,11 +302,12 @@ class MainWindow(QMainWindow):
|
|||||||
"""Setup system tray icon."""
|
"""Setup system tray icon."""
|
||||||
self.tray_icon = QSystemTrayIcon(self)
|
self.tray_icon = QSystemTrayIcon(self)
|
||||||
|
|
||||||
# Load icon
|
# Load icon from bundled resources
|
||||||
icon_path = os.path.join(self.app_dir, "Macro Pad.png")
|
icon_path = get_resource_path("Macro Pad.png")
|
||||||
if os.path.exists(icon_path):
|
if os.path.exists(icon_path):
|
||||||
self.tray_icon.setIcon(QIcon(icon_path))
|
icon = QIcon(icon_path)
|
||||||
self.setWindowIcon(QIcon(icon_path))
|
self.tray_icon.setIcon(icon)
|
||||||
|
self.setWindowIcon(icon)
|
||||||
else:
|
else:
|
||||||
self.tray_icon.setIcon(self.style().standardIcon(QStyle.StandardPixmap.SP_ComputerIcon))
|
self.tray_icon.setIcon(self.style().standardIcon(QStyle.StandardPixmap.SP_ComputerIcon))
|
||||||
|
|
||||||
|
|||||||
21
main.py
21
main.py
@@ -7,21 +7,32 @@ import multiprocessing
|
|||||||
|
|
||||||
|
|
||||||
def get_app_dir():
|
def get_app_dir():
|
||||||
"""Get the application directory."""
|
"""Get the application directory (where macros.json and macro_images are stored)."""
|
||||||
if getattr(sys, 'frozen', False):
|
if getattr(sys, 'frozen', False):
|
||||||
# Running as compiled executable
|
# Running as compiled executable - use executable's directory for user data
|
||||||
return os.path.dirname(sys.executable)
|
return os.path.dirname(sys.executable)
|
||||||
else:
|
else:
|
||||||
# Running as script
|
# Running as script
|
||||||
return os.path.dirname(os.path.abspath(__file__))
|
return os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
|
||||||
|
def get_resource_path(relative_path):
|
||||||
|
"""Get the path to a bundled resource file."""
|
||||||
|
if getattr(sys, 'frozen', False):
|
||||||
|
# Running as compiled executable - resources are in _MEIPASS
|
||||||
|
base_path = sys._MEIPASS
|
||||||
|
else:
|
||||||
|
# Running as script - resources are in the script directory
|
||||||
|
base_path = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
return os.path.join(base_path, relative_path)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""Main entry point."""
|
"""Main entry point."""
|
||||||
# Required for multiprocessing on Windows
|
# Required for multiprocessing on Windows
|
||||||
multiprocessing.freeze_support()
|
multiprocessing.freeze_support()
|
||||||
|
|
||||||
# Get app directory
|
# Get directories
|
||||||
app_dir = get_app_dir()
|
app_dir = get_app_dir()
|
||||||
|
|
||||||
# Import PySide6 after freeze_support
|
# Import PySide6 after freeze_support
|
||||||
@@ -34,8 +45,8 @@ def main():
|
|||||||
app.setApplicationName("MacroPad Server")
|
app.setApplicationName("MacroPad Server")
|
||||||
app.setOrganizationName("MacroPad")
|
app.setOrganizationName("MacroPad")
|
||||||
|
|
||||||
# Set application icon
|
# Set application icon (from bundled resources)
|
||||||
icon_path = os.path.join(app_dir, "Macro Pad.png")
|
icon_path = get_resource_path("Macro Pad.png")
|
||||||
if os.path.exists(icon_path):
|
if os.path.exists(icon_path):
|
||||||
app.setWindowIcon(QIcon(icon_path))
|
app.setWindowIcon(QIcon(icon_path))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user