添加QgsApplication导入后PyInstaller打包PyQGIS程序报错求助
问题分析
你遇到的崩溃报错核心原因有两个:一是PyInstaller未自动识别QGIS核心库依赖的PyQt5.QtPositioning模块;二是你的TestEXE.spec文件存在语法错误(hiddenimports行末尾缺少逗号,导致后续参数无法被正确解析)。
解决方案步骤
1. 修复spec文件语法错误
原spec中hiddenimports行末尾未加逗号,导致hookspath=None等后续参数被错误归为hiddenimports的内容,必须补上逗号修正语法。
2. 添加缺失的隐藏导入
将PyQt5.QtPositioning及QGIS核心依赖的其他常见PyQt模块添加到hiddenimports,避免后续出现类似模块缺失错误。
3. 完整打包QGIS运行环境
QGIS除Python模块外,还依赖大量二进制库、资源文件,需通过binaries和datas将这些文件纳入打包范围(需替换为你的实际QGIS安装路径)。
4. 初始化QgsApplication(必要操作)
你的代码仅导入了QgsApplication但未初始化,这会导致QGIS核心功能无法正常工作,必须添加初始化及清理逻辑。
修改后的文件示例
修改后的TestEXE.spec
import os import sys # 替换为你的QGIS实际安装路径 QGIS_PATH = "C:/Program Files/QGIS 3.34" sys.path.append(os.path.join(QGIS_PATH, "python")) block_cipher = None workdir = os.getenv('VIEWER_DIR') a = Analysis( ['main.py'], pathex=[workdir, os.path.join(QGIS_PATH, "python")], binaries=[ # 添加QGIS核心二进制库 (os.path.join(QGIS_PATH, "bin/*.dll"), "bin"), (os.path.join(QGIS_PATH, "apps/qgis-ltr/bin/*.dll"), "apps/qgis-ltr/bin"), ], datas=[ (os.path.join(workdir,'testdata/*'),'testdata'), (os.path.join(workdir,'qgis_plugins/*'),'qgis_plugins'), (os.path.join(workdir,'graphics/*'),'graphics'), # 添加QGIS Python资源与插件 (os.path.join(QGIS_PATH, "python/qgis"), "qgis"), (os.path.join(QGIS_PATH, "apps/qgis-ltr/resources"), "resources"), ], hiddenimports=[ 'qgis.PyQt.QtWidgets', 'qgis.core.QgsApplication', 'PyQt5.QtPositioning', 'PyQt5.QtXml', 'PyQt5.QtSvg', 'PyQt5.QtNetwork', 'qgis.core', 'qgis.gui' ], hookspath=None, runtime_hooks=None, excludes=None, win_no_prefer_redirects=None, win_private_assemblies=None, cipher=block_cipher ) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE( pyz, a.scripts, [], exclude_binaries=True, name='TestEXE', debug=True, bootloader_ignore_signals=False, strip=False, upx=True, console=True, # 调试阶段开启控制台查看错误信息,完成后可改为False icon='graphics/airports.ico' ) coll = COLLECT( exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, upx_exclude=[], name='TestEXE' )
修改后的main.py
import sys import os # 设置QGIS环境变量(替换为你的实际安装路径) QGIS_PATH = "C:/Program Files/QGIS 3.34" os.environ["QGIS_PREFIX_PATH"] = os.path.join(QGIS_PATH, "apps/qgis-ltr") sys.path.append(os.path.join(QGIS_PATH, "python")) from qgis.PyQt.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, QLabel from qgis.core import QgsApplication class MainWindow(QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setWindowTitle("Mapová prezeračka --- Pebieha načítanie dát ...") self.init_gui() self.show() def init_gui(self): self.formular = QWidget() layoutFormulara = QHBoxLayout() self.formular.setLayout(layoutFormulara) boxLayout1 = QHBoxLayout() boxLayout2 = QHBoxLayout() layoutFormulara.addStretch() layoutFormulara.addLayout(boxLayout1) layoutFormulara.addLayout(boxLayout2) layoutFormulara.addStretch() self.label1 = QLabel("Hello") boxLayout1.addWidget(self.label1) self.setCentralWidget(self.formular) def main(): # 初始化QgsApplication qgs_app = QgsApplication([], False) qgs_app.initQgis() # 创建主窗口 mainWin = MainWindow() mainWin.show() # 运行应用 try: retval = app.exec_() # 退出前清理QGIS资源 qgs_app.exitQgis() sys.exit(retval) except SystemExit: print("sys.exit() fungovalo podľa očakávania") qgs_app.exitQgis() except Exception as e: print(f"Niečo sa strašne pokazilo: {str(e)}") qgs_app.exitQgis() if __name__ == "__main__": app = QApplication(sys.argv) main()
额外注意事项
- 务必将
QGIS_PATH替换为你实际的QGIS安装目录,版本号需与安装版本匹配。 - 打包时使用命令:
pyinstaller TestEXE.spec,不要直接打包py文件。 - 若后续仍出现其他模块缺失错误,将对应模块添加到
hiddenimports即可。
内容的提问来源于stack exchange,提问作者Stano
相关产品推荐
相关产品推荐

