Pyinstaller打包PyQt5生成的.app程序窗口失焦无法输入求助
解决PyQt5应用打包成macOS .app后输入框无法获取焦点的问题
这是macOS下PyInstaller打包PyQt5应用时挺常见的焦点管理问题,我之前处理过类似的情况,给你几个针对性的排查和解决思路:
1. 调整spec文件中BUNDLE与COLLECT的执行顺序
你的spec文件里,不管是不是macOS系统,最后都执行了COLLECT命令,这会导致macOS下同时生成.app包和普通的文件夹结构,可能干扰.app的正确启动上下文,进而引发焦点异常。
修改spec文件,让COLLECT只在非macOS平台执行:
-*- mode: python -*- import sys import os block_cipher = None a = Analysis(['nbfixer_decoupled.py'], pathex=['/Users/peterpetocz/Desktop/NBFixer_app'], binaries=[], datas=[], hiddenimports=[], hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False) a.datas+=[('./login.properties','./login.properties','DATA'),('./status.properties','./status.properties','DATA'),('./signature.properties','./signature.properties','DATA')] pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) # 针对macOS打包成.app if sys.platform == 'darwin': exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, name='NBFixer', debug=False, strip=False, upx=True, runtime_tmpdir=None, console=True, icon='nbfixer.icns') app = BUNDLE(exe, name='NBFixer.app', info_plist={ 'NSHighResolutionCapable': 'True' }, icon='nbfixer.icns') else: # 仅在非macOS平台生成文件夹结构 coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, name='nbfixer_decoupled')
2. 关闭EXE的console参数
你当前设置了console=True,这会让.app启动时弹出终端窗口,终端窗口会抢占系统焦点,导致Qt应用的输入框无法获取焦点。
把EXE行的console=True改成console=False:
exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, name='NBFixer', debug=False, strip=False, upx=True, runtime_tmpdir=None, console=False, icon='nbfixer.icns')
如果后续需要查看日志,可以再改回来,但先测试这个调整是否解决焦点问题。
3. 确保Qt的macOS平台插件正确打包
PyInstaller有时会漏掉Qt的libqcocoa.dylib平台插件,这会导致窗口管理异常。可以手动把插件添加到datas中:
from PyQt5.QtCore import QLibraryInfo # 获取Qt插件路径并添加到datas qt_platform_path = os.path.join(QLibraryInfo.location(QLibraryInfo.PluginsPath), 'platforms') a.datas += [ (os.path.join('platforms', 'libqcocoa.dylib'), os.path.join(qt_platform_path, 'libqcocoa.dylib'), 'BINARY') ]
4. 修正应用启动时的工作目录
.app启动时默认工作目录是根目录/,而Unix可执行文件是在当前目录运行,路径差异可能导致资源加载异常,间接引发焦点问题。在你的PyQt应用代码开头添加以下代码:
import os import sys if hasattr(sys, '_MEIPASS'): # 从PyInstaller包启动时,切换到包内的资源目录 os.chdir(sys._MEIPASS) else: # 从源码启动时,切换到脚本所在目录 os.chdir(os.path.dirname(os.path.abspath(__file__)))
建议先尝试前两个调整,这是最常见的导致该问题的原因,大部分情况下都能解决焦点异常。
内容的提问来源于stack exchange,提问作者Peter Petocz
相关产品推荐
相关产品推荐

