@@ -41,10 +41,159 @@ a = Analysis(
4141 hookspath = [],
4242 hooksconfig = {},
4343 runtime_hooks = [],
44- excludes = [],
44+ excludes = [
45+ # ── Aggressively trim unneeded PySide6 modules ──
46+ "PySide6.QtWebEngine" ,
47+ "PySide6.QtWebEngineCore" ,
48+ "PySide6.QtWebEngineWidgets" ,
49+ "PySide6.QtWebChannel" ,
50+ "PySide6.QtWebSockets" ,
51+ "PySide6.Qt3DCore" ,
52+ "PySide6.Qt3DRender" ,
53+ "PySide6.Qt3DInput" ,
54+ "PySide6.Qt3DLogic" ,
55+ "PySide6.Qt3DAnimation" ,
56+ "PySide6.Qt3DExtras" ,
57+ "PySide6.QtMultimedia" ,
58+ "PySide6.QtMultimediaWidgets" ,
59+ "PySide6.QtBluetooth" ,
60+ "PySide6.QtNfc" ,
61+ "PySide6.QtPositioning" ,
62+ "PySide6.QtLocation" ,
63+ "PySide6.QtSensors" ,
64+ "PySide6.QtSerialPort" ,
65+ "PySide6.QtSerialBus" ,
66+ "PySide6.QtTest" ,
67+ "PySide6.QtPdf" ,
68+ "PySide6.QtPdfWidgets" ,
69+ "PySide6.QtCharts" ,
70+ "PySide6.QtDataVisualization" ,
71+ "PySide6.QtRemoteObjects" ,
72+ "PySide6.QtScxml" ,
73+ "PySide6.QtSql" ,
74+ "PySide6.QtTextToSpeech" ,
75+ "PySide6.QtQuick3D" ,
76+ "PySide6.QtVirtualKeyboard" ,
77+ "PySide6.QtGraphs" ,
78+ "PySide6.Qt5Compat" ,
79+ # ── PySide6 designer / tools (not needed at runtime) ──
80+ "PySide6.QtDesigner" ,
81+ "PySide6.QtHelp" ,
82+ "PySide6.QtUiTools" ,
83+ "PySide6.QtXml" ,
84+ "PySide6.QtConcurrent" ,
85+ "PySide6.QtStateMachine" ,
86+ "PySide6.QtHttpServer" ,
87+ "PySide6.QtSpatialAudio" ,
88+ # ── Other unused stdlib modules ──
89+ "unittest" ,
90+ "xmlrpc" ,
91+ "pydoc" ,
92+ "doctest" ,
93+ "tkinter" ,
94+ "test" ,
95+ "distutils" ,
96+ "setuptools" ,
97+ "ensurepip" ,
98+ "lib2to3" ,
99+ "idlelib" ,
100+ "turtledemo" ,
101+ "turtle" ,
102+ "sqlite3" ,
103+ "multiprocessing" ,
104+ ],
45105 noarchive = False ,
46106)
47107
108+ # ── Filter collected Qt shared libs / plugins that PyInstaller hooks may have pulled in ──
109+ UNWANTED_PATTERNS = [
110+ "QtWebEngine" ,
111+ "QtWebChannel" ,
112+ "QtWebSockets" ,
113+ "Qt3D" ,
114+ "QtMultimedia" ,
115+ "QtMultimediaWidgets" ,
116+ "QtBluetooth" ,
117+ "QtLocation" ,
118+ "QtPositioning" ,
119+ "QtSensors" ,
120+ "QtSerialPort" ,
121+ "QtPdf" ,
122+ "QtCharts" ,
123+ "QtDataVisualization" ,
124+ "QtRemoteObjects" ,
125+ "QtTextToSpeech" ,
126+ "QtQuick3D" ,
127+ "QtVirtualKeyboard" ,
128+ "QtGraphs" ,
129+ "Qt5Compat" ,
130+ "QtWebView" ,
131+ "QtTest" ,
132+ "QtLabsAnimation" ,
133+ "QtLabsFolderListModel" ,
134+ "QtLabsPlatform" ,
135+ "QtLabsQmlModels" ,
136+ "QtLabsSettings" ,
137+ "QtLabsSharedImage" ,
138+ "QtLabsWavefrontMesh" ,
139+ "QtQuickTest" ,
140+ "QtScxml" ,
141+ "QtScxmlQml" ,
142+ "QtSpatialAudio" ,
143+ "QtSql" ,
144+ ]
145+
146+ # QtQuick.Controls.Material imports QtQuick.Controls.Basic, so keep the
147+ # Material and Basic stacks but drop the other optional style families.
148+ UNUSED_QUICK_CONTROLS_PATTERNS = [
149+ "QtQuickControls2Fusion" ,
150+ "QtQuickControls2FusionStyleImpl" ,
151+ "QtQuickControls2Imagine" ,
152+ "QtQuickControls2ImagineStyleImpl" ,
153+ "QtQuickControls2Universal" ,
154+ "QtQuickControls2UniversalStyleImpl" ,
155+ "QtQuickControls2FluentWinUI3StyleImpl" ,
156+ "QtQuickControls2IOSStyleImpl" ,
157+ "QtQuickControls2MacOSStyleImpl" ,
158+ ]
159+
160+ UNUSED_QUICK_CONTROLS_QML_DIRS = [
161+ "/qtquick/controls/fusion/" ,
162+ "/qtquick/controls/fluentwinui3/" ,
163+ "/qtquick/controls/imagine/" ,
164+ "/qtquick/controls/universal/" ,
165+ "/qtquick/controls/ios/" ,
166+ "/qtquick/controls/macos/" ,
167+ ]
168+
169+ def is_unwanted (path_or_toc_entry ):
170+ # entry can be a (src, dest) tuple (TOC) or a string path
171+ src = ""
172+ if isinstance (path_or_toc_entry , (list , tuple )) and len (path_or_toc_entry ) >= 1 :
173+ src = path_or_toc_entry [0 ] or ""
174+ elif isinstance (path_or_toc_entry , str ):
175+ src = path_or_toc_entry
176+ src_lower = src .lower ()
177+ for pat in UNWANTED_PATTERNS :
178+ if pat .lower () in src_lower :
179+ return True
180+ for pat in UNUSED_QUICK_CONTROLS_PATTERNS :
181+ if pat .lower () in src_lower :
182+ return True
183+ for qml_dir in UNUSED_QUICK_CONTROLS_QML_DIRS :
184+ if qml_dir in src_lower :
185+ return True
186+ # also drop plugin subdirectories commonly unused (webengine, multimedia, printsupport, etc.)
187+ if "/plugins/" in src_lower :
188+ for pat in ("webengine" , "multimedia" , "printsupport" , "qmltooling" , "sensorgestures" ):
189+ if pat in src_lower :
190+ return True
191+ return False
192+
193+ # Filter Analysis.toc lists (binaries and datas)
194+ a .binaries = [b for b in a .binaries if not is_unwanted (b )]
195+ a .datas = [d for d in a .datas if not is_unwanted (d )]
196+
48197pyz = PYZ (a .pure )
49198
50199exe = EXE (
0 commit comments