【发布时间】:2021-10-24 18:32:44
【问题描述】:
我有一个 gui 程序,我用它来处理扫描的 pdf 并查找带有 QR 码的页面,它告诉程序在哪里将 pdf 拆分为多个文件。我的程序本质上是一个函数列表,随着每个步骤的完成,它们会一个接一个地相互调用。
当我尝试使用 pyinstaller 将其编译为 exe 时,我遇到了麻烦。我的程序作为 python 文件运行良好,并且在我指定 --noconsole 和 --onefile 选项时也能正常运行。当我同时使用两者时,我无法开始工作。出于某种原因,尝试使用 --onefile 和 --noconsole 获得一个工作程序不可避免地会失败。它启动得很好,但总是在同一部分失败。以下是失败部分的代码:
import PySimpleGUI as sg
import shutil
import pathlib
from pyzbar.pyzbar import decode
from pyzbar.pyzbar import ZBarSymbol
from json import loads
from pdf2image import convert_from_path
import fitz
import win32com.client
import win32timezone
import os
import os.path
from os import path
from datetime import datetime, timedelta
from sys import exit
import tempfile
def scan_reader(filepath):
'''takes a filepath pointing to a pdf file and returns the number of pages, as well as any QR data that could be pulled from the pages'''
# Converts the pdf into a list of images, one for each page
images = convert_from_path(filepath, size = (500, None), dpi = 300, poppler_path = 'bin', grayscale=True)
# For each page image: searches page for QR, and if qr is found it adds it to the page_qr_data dictionary in the format page number:qr data
page_qr_data = {}
for idx, image in enumerate(images):
# Decode the QR image
detectedBarcodes = decode(image, symbols=[ZBarSymbol.QRCODE])
# If not detected then continue to the next page
if not detectedBarcodes:
continue
else:
# If QR detected, adds the page number to page_qr_data as a key and makes a list of the qr data for the value
page_qr_data[idx] = []
for barcode in detectedBarcodes:
page_qr_data[idx].append(barcode.data)
return len(images), page_qr_data
def scan_reader_window():
'''Presents the user with a list of files that have been pulled and asks them to select which ones they'd like to import'''
files = os.listdir(temp_pdf_dir)
receivers_dict = {}
page_lengths = {}
i = 0
for file in files:
if sg.one_line_progress_meter('Processing files...', i+1, len(files), f'(Step 2 of 2) Processing files...\n{file}', key = 'file_processor', orientation = 'horizontal'):
filepath = f'{temp_pdf_dir}/{file}'
page_lengths[file], raw_scan_data = scan_reader(filepath)
for key, value in raw_scan_data.copy().items():
if len(value) > 1:
del raw_scan_data[key]
raw_scan_data[key] = value[0]
for key, value in raw_scan_data.copy().items():
try:
raw_scan_data[key] = loads(value)
except:
del raw_scan_data[key]
for key, value in raw_scan_data.copy().items():
if 'DB_FILENAME: ' not in value:
del raw_scan_data[key]
else:
raw_scan_data[key] = value[20:]
receivers_dict[file] = raw_scan_data
i += 1
elif i == len(files)-1:
filepath = f'{temp_pdf_dir}/{file}'
page_lengths[file], raw_scan_data = scan_reader(filepath)
for key, value in raw_scan_data.copy().items():
if len(value) > 1:
del raw_scan_data[key]
raw_scan_data[key] = value[0]
for key, value in raw_scan_data.copy().items():
try:
raw_scan_data[key] = loads(value)
except:
del raw_scan_data[key]
for key, value in raw_scan_data.copy().items():
if 'DB_FILENAME: ' not in value:
del raw_scan_data[key]
else:
raw_scan_data[key] = value[20:]
receivers_dict[file] = raw_scan_data
i += 1
else:
clutter = os.listdir(temp_pdf_dir)
for file in clutter:
os.remove(f'{temp_pdf_dir}/{file}')
exit()
layout = []
for value in receivers_dict.values():
for filename in value.values():
layout.append([sg.Checkbox(filename, default = True, background_color = 'white')])
window = sg.Window('Scans', resizable = True, icon = parker_icon).Layout([ [sg.Text('Check all of the scans you wish to import.')],
[sg.Column(layout, scrollable=True, background_color = 'white', size = (350,350), expand_x = True, expand_y = True, justification = 'center', key = 'scans_column')],
[sg.Text("Save location:"), sg.Input(default_text = 'F:/Receiving/Receivers', key = 'selected_files'), sg.FolderBrowse(initial_folder = 'F:/Receiving/Receivers')],
[sg.Button('Continue'), sg.Button('Cancel')] ])
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event=='Cancel':
clutter = os.listdir(temp_pdf_dir)
for file in clutter:
os.remove(f'{temp_pdf_dir}/{file}')
exit()
elif event == "Continue":
save_location = values.pop('selected_files')
del values['Browse']
page_download_dict = {}
for filename in receivers_dict.keys():
page_download_dict[filename] = {}
for key, value in receivers_dict.items():
for page, filename in value.items():
page_download_dict[key][filename] = [page]
for key, value in page_download_dict.items():
for idx, (po_key, page_list) in enumerate(reversed(value.items())):
if idx == 0:
page_list.append(page_lengths[key]-1)
start_page = page_list[0]
else:
page_list.append(start_page-1)
start_page = page_list[0]
i = 0
for value in page_download_dict.values():
for v in value.values():
v.append(values[i])
i += 1
window.close()
pdf_split_page(page_download_dict, len(values), save_location)
我没有包含整个程序,因为它将近 400 行,但如果您觉得需要它,我会很高兴。函数 scan_reader_window() 每次都会失败。具体来说,我知道它在第一个 for 循环中的某个位置,在 sg.one_line_progress_meter 之后,因为进度表拉起,但函数在完成第一次迭代之前失败。
同样,这可以完美地作为 python 文件工作,并且在指定 --noconsole 或 --onefile 时作为 exe 工作。只有当我尝试两者都做时它才会失败,而且我终其一生都无法弄清楚原因。有人有什么想法吗? 谢谢!
编辑:这似乎是一个poppler问题。我尝试使用 --debug 运行它,在它崩溃后我收到弹出消息“无法获取页数。是否安装了 poppler 并在 PATH 中?”我已经修改了我的代码,以便“poppler_path = 'bin'”,并将 bin 添加到我的规范文件中,如下所示: datas=[('D:/Coding/bin', 'bin')] 但仍然没有运气。另外,因为它是被请求的,所以这里是来自 pyinstaller 的日志(对不起,当我从控制台复制时,它会去除换行符,不确定如何更好地格式化):
D:\Coding\Portable_Python-3.9.4_x64\App\Python\Scripts>pyinstaller "receiver_scan_import_wizard.spec" 84 信息:PyInstaller:4.3 84 信息:Python:3.9.4 84 信息:平台:Windows-10-10.0 .18362-SP0 84 信息:UPX 不可用。 131 信息:使用路径扩展 PYTHONPATH ['D:\Work\Receiver Scan Import Wizard','D:\Coding\Portable_Python-3.9.4_x64\App\Python\Scripts'] 147 信息:检查分析 147 信息:构建分析,因为Analysis-00.toc 不存在 147 信息:正在初始化模块依赖关系图... 147 信息:缓存模块图挂钩... 162 警告:为模块“win32ctypes.core”定义了几个挂钩。请注意它们不要冲突。 169 信息:分析 base_library.zip ... 2235 信息:处理来自 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks\pre_find_module_path\ 的预查找模块路径挂钩 distutils钩-distutils.py'。 2235 信息:distutils:重定向到非 venv 目录 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib' 4793 信息:缓存模块依赖关系图... 5003 信息:运行 Analysis Analysis-00.toc 5003信息:将 Microsoft.Windows.Common-Controls 添加到 d:\coding\portable_python-3.9.4_x64\app\python\python.exe 所需的最终可执行文件的依赖程序集 5066 警告:找不到库:api-ms-win-core d:\coding\portable_python-3.9.4_x64\app\python\python39.dll 的 -path-l1-1-0.dll 依赖项 5066 信息:分析 D:\Work\Receiver 扫描导入向导\receiver_scan_import_wizard.py 5724 信息:处理来自“D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks\pre_find_module_path\hook-site.py”的预查找模块路径挂钩站点。 5724 信息:站点:重定向到 fake-dir 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\fake-modules' 7771 信息:处理安全前导入模块挂钩设置工具。 extern.six.moves 来自 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks\pre_safe_import_module\hook-setuptools.extern.six.moves.py'。 10513 信息:处理来自“D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\_pyinstaller_hooks_contrib\hooks\pre_safe_import_module\hook-win32com.py”的安全前导入模块挂钩 win32com。 10948 信息:处理模块挂钩... 10948 信息:从 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\_pyinstaller_hooks_contrib\hooks\stdhooks 加载模块挂钩 'hook-pythoncom.py' '... 11198 信息:从 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\_pyinstaller_hooks_contrib\hooks\stdhooks' 加载模块挂钩 'hook-pywintypes.py'... 11445信息:从“D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\_pyinstaller_hooks_contrib\hooks\stdhooks”加载模块挂钩“hook-win32com.py”... 11498 信息:加载模块挂钩'hook-win32ctypes.core.py' 来自'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\_pyinstaller_hooks_contrib\hooks\stdhooks'... 11630 信息:加载模块挂钩'hook- PIL.Image.py' 来自 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks'... 11915 信息:加载模块挂钩 'hook-PIL.ImageFilter.py ' 来自 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\l ib\site-packages\PyInstaller\hooks'... 11915 信息:从'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages 加载模块挂钩'hook-PIL.SpiderImagePlugin.py' \PyInstaller\hooks'... 11915 信息:未找到要排除的导入:'FixTk' 11915 信息:从 'D:\Coding\Portable_Python-3.9.4_x64\App\Python 加载模块挂钩 'hook-PIL.py' \lib\site-packages\PyInstaller\hooks'... 11915 信息:未找到要排除的导入:'FixTk' 11915 信息:从'D:\Coding\Portable_Python-3.9 加载模块挂钩'hook-_tkinter.py' .4_x64\App\Python\lib\site-packages\PyInstaller\hooks'... 12100 信息:检查树 12100 信息:构建树,因为 Tree-00.toc 不存在 12100 信息:构建树 Tree-00.toc 12200信息:检查树 12200 信息:构建树,因为 Tree-01.toc 不存在 12200 信息:构建树 Tree-01.toc 12316 信息:检查树 12316 信息:构建树,因为 Tree-02.toc 不存在 12316 信息:建筑树 Tree-02.toc 12332信息:从“D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks”加载模块挂钩“hook-difflib.py”... 12332 信息:加载模块挂钩“挂钩” -distutils.py' 来自 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks'... 12332 信息:加载模块挂钩 'hook-distutils.util.py'来自 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks'... 12332 信息:从 'D:\Coding\ 加载模块挂钩 'hook-encodings.py' Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks'... 12417 信息:从'D:\Coding\Portable_Python-3.9.4_x64\App 加载模块挂钩'hook-heapq.py' \Python\lib\site-packages\PyInstaller\hooks'... 12417 信息:从 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site- 加载模块挂钩 'hook-importlib_metadata.py' packages\PyInstaller\hooks'... 12417 信息:从 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib 加载模块挂钩 'hook-lib2to3.py' \site-packages\PyInstaller\hooks'... 12448 信息:从 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\ 加载模块挂钩 'hook-multiprocessing.util.py' PyInstaller\hooks'... 12464 信息:从“D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks”加载模块挂钩“hook-numpy._pytesttester.py”。 .. 12464 信息:从“D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks”加载模块挂钩“hook-numpy.py”... 12517 信息:导入到被排除未找到:'f2py' 12533 信息:从 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks' 加载模块挂钩 'hook-pickle.py'.. . 12533 信息:从 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks' 加载模块挂钩 'hook-pkg_resources.py'... 13106 警告:隐藏导入“ pkg_resources.py2_warn" 未找到! 13318 警告:未找到隐藏的导入“pkg_resources.markers”! 13320 信息:从“D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks”加载模块挂钩“hook-scipy.py”... 13320 信息:加载模块挂钩“ hook-setuptools.py' 来自 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks'... D:\Coding\Portable_Python-3.9.4_x64\App\Python \lib\site-packages\setuptools\distutils_patch.py:25: UserWarning: Distutils 在 Setuptools 之前被导入。不鼓励这种用法,并且可能会出现不良行为或错误。请直接使用 Setuptools 的对象或至少先导入 Setuptools。 warnings.warn(13822 信息:从“D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks”加载模块挂钩“hook-sysconfig.py”... 13831 信息:从“D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks”加载模块挂钩“hook-xml.dom.domreg.py”... 13831 信息:加载模块挂钩'hook-xml.etree.cElementTree.py' 来自'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks'... 13831 信息:加载模块挂钩'hook- xml.py' 来自 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks'... 13831 信息:从 'D 加载模块挂钩 'hook-packaging.py' :\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks'... 13831 信息:从'D:\Coding\Portable_Python 加载模块挂钩'hook-setuptools.msvc.py' -3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks'... 13856 信息:寻找 ctypes DLL 13903 信息:分析运行时挂钩 .. . 13919 信息:包括运行时挂钩 'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_multiprocessing.py' 13919 信息:包括运行时挂钩' D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_win32api.py' 13919 信息:包括运行时挂钩'D:\Coding\Portable_Python-3.9.4_x64 \App\Python\lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_win32comgenpy.py' 13919 信息:包括运行时挂钩'D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages \PyInstaller\hooks\rthooks\pyi_rth__tkinter.py' 13919 信息:寻找动态库 14462 信息:寻找彩蛋 14462 信息:使用 Python 库 d:\coding\portable_python-3.9.4_x64\app\python\python39.dll 14462 信息:找到绑定重定向:[] 14562 信息:警告写入 D:\Coding\Portable_Python-3.9.4_x64\App\Python\Scripts\build\receiver_scan_import_wizard\warn-receiver_scan_import_wizard.txt 1461 9 信息:图形交叉引用写入 D:\Coding\Portable_Python-3.9.4_x64\App\Python\Scripts\build\receiver_scan_import_wizard\xref-receiver_scan_import_wizard.html 14718 信息:从 .spec 追加“二进制文件” 14718 信息:追加“来自 .spec 14718 信息的数据:检查 PYZ 14718 信息:构建 PYZ 因为 PYZ-00.toc 不存在 14718 信息:构建 PYZ (ZlibArchive) D:\Coding\Portable_Python-3.9.4_x64\App\Python\Scripts\build \receiver_scan_import_wizard\PYZ-00.pyz 14734 信息:构建 PYZ (ZlibArchive) D:\Coding\Portable_Python-3.9.4_x64\App\Python\Scripts\build\receiver_scan_import_wizard\PYZ-00.pyz 成功完成。 14772 信息:检查 PKG 14772 信息:构建 PKG,因为 PKG-00.toc 不存在 14772 信息:构建 PKG (CArchive) PKG-00.pkg 30699 信息:构建 PKG (CArchive) PKG-00.pkg 已成功完成。 30795 信息:引导加载程序 D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\bootloader\Windows-64bit\runw_d.exe 30796 信息:检查 EXE 30797 信息:构建 EXE,因为 EXE-00 .toc 不存在 30797 信息:从 EXE-00.toc 构建 EXE 30977 信息:从 ['D:\Coding\Portable_Python-3.9.4_x64\App\Python\lib\site-packages\PyInstaller\bootloader\images 复制图标\icon-windowed.ico'] 30990 信息:用 104 字节写入 RT_GROUP_ICON 0 资源 30990 信息:用 3752 字节写入 RT_ICON 1 资源 30991 信息:用 2216 字节写入 RT_ICON 2 资源 30992 信息:用 1384 字节写入 RT_ICON 3 资源 30992 信息:使用 38188 字节写入 RT_ICON 4 资源 30993 信息:使用 9640 字节写入 RT_ICON 5 资源 30994 信息:使用 4264 字节写入 RT_ICON 6 资源 30994 信息:使用 1128 字节写入 RT_ICON 7 资源 31031 信息:在 D:\Coding\Portable_Python 中更新清单-3.9.4_x64\App\Python\Scripts\build\receiver_scan_impo rt_wizard\runw_d.exe.efjmscdq 31040 信息:更新资源类型 24 名称 1 语言 0 31211 信息:将存档附加到 EXE D:\Coding\Portable_Python-3.9.4_x64\App\Python\Scripts\dist\receiver_scan_import_wizard.exe 37778 信息:从 EXE-00.toc 构建 EXE 已成功完成。
【问题讨论】:
-
你的意思是它在某些地方失败了?它压碎了吗?到底发生了什么?您可以添加从 pyinstaller 获得的日志吗?
-
我的意思是它到达了打开one_line_progress_meter(key=file_processor)的地步,然后在它完成第一次迭代之前,会弹出一个标题为“检测到致命错误”的消息框上面写着“无法执行脚本 my_script”。当我点击确定时,进度表关闭并且程序过早结束。我现在会将日志添加到我的原始帖子中,并使用我学到的一些新信息进行更新,这可能会有所帮助。这似乎是一个令人费解的问题。
标签: python pyinstaller