# -*- mode: python ; coding: utf-8 -*- import os import sys import PyQt5 # --- MONKEYPATCH PyInstaller QT Detection (Force correct path) --- try: from PyInstaller.utils.hooks import qt # 1. Find the real plugin path qt5_dir = os.path.dirname(PyQt5.__file__) possible_plugin_paths = [ os.path.join(qt5_dir, 'Qt', 'plugins'), os.path.join(qt5_dir, 'plugins'), ] real_plugin_path = None for p in possible_plugin_paths: if os.path.exists(p): real_plugin_path = p break # 2. Override the failing function if real_plugin_path: print(">>> FORCING QT PLUGINS PATH: {}".format(real_plugin_path)) # Save original just in case, though we ignore it original_qt_plugins_dir = qt.qt_plugins_dir def new_qt_plugins_dir(namespace=None): return real_plugin_path qt.qt_plugins_dir = new_qt_plugins_dir # Also set env var as backup os.environ['QT_PLUGIN_PATH'] = real_plugin_path else: print(">>> ERROR: Could not find PyQt5 plugins to monkeypatch!") except ImportError: print(">>> WARNING: Could not import PyInstaller.utils.hooks.qt for patching") except Exception as e: print(">>> WARNING: Monkeypatch failed: {}".format(e)) # ----------------------------------------------------------------------------- block_cipher = None a = Analysis( ['main.py'], pathex=[], binaries=[], # Bundle tools to sql_tools subfolder datas=[ ('icon.png', '.'), ('sql_tools/pg_dump.exe', 'sql_tools'), ('sql_tools/mysqldump.exe', 'sql_tools') ], hiddenimports=['PyQt5', 'pymysql', 'psycopg2', 'apscheduler'], hookspath=[], runtime_hooks=['rthook_qt_fix.py'], # Context7 Optimization: Exclude unused modules to reduce size excludes=['FixTk', 'tcl', 'tk', '_tkinter', 'tkinter', 'Tkinter', 'matplotlib', 'numpy', 'scipy', 'pandas', 'PIL.ImageTk'], win_no_prefer_redirects=False, cipher=block_cipher, ) # --- MANUAL BUNDLING OF PLATFORMS (Fix "platform plugin windows not found") --- # Re-locate the plugins directory (redundant but safe) qt5_dir = os.path.dirname(PyQt5.__file__) plugin_sources = [ os.path.join(qt5_dir, 'Qt', 'plugins', 'platforms'), os.path.join(qt5_dir, 'plugins', 'platforms'), ] found_plugin = None for p in plugin_sources: if os.path.exists(p): found_plugin = p break if found_plugin: print(">>> MANUALLY BUNDLING PLATFORMS FROM: {}".format(found_plugin)) a.datas += Tree(found_plugin, prefix='platforms') # Bundle as root/platforms/ # Also bundle as root/qt/plugins/platforms just to match common fallback paths # a.datas += Tree(found_plugin, prefix='qt/plugins/platforms') else: print(">>> ERROR: Could not find 'platforms' folder for bundling!") # ----------------------------------------------------------------------------- pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) # ONEFILE Mode: Everything bundled into single EXE exe = EXE( pyz, a.scripts, a.binaries, a.zipfiles, a.datas, [], name='ProBackup', debug=False, bootloader_ignore_signals=False, strip=False, upx=False, upx_exclude=[], runtime_tmpdir=None, console=False, icon='icon.ico', )