PyInstaller打包Python条码生成程序为exe时遇OSError问题求助
Python条码生成程序PyInstaller打包后OSError问题解决
问题重现
- 本地运行
.py或.ipynb脚本时功能正常,使用PyInstaller打包为exe可执行文件后,执行条码生成操作触发OSError: cannot open resource错误 - 完整代码:
import tkinter as tk from tkinter import filedialog, messagebox from barcode import Code128 from barcode.writer import ImageWriter from reportlab.lib.pagesizes import letter from reportlab.pdfgen import canvas class BarcodeGeneratorApp: def __init__(self, master): self.master = master self.master.title("Barcode Generator") self.label_numbers = tk.Label(self.master, text="Barcode:") self.label_numbers.grid(row=0, column=0, padx=10, pady=10, sticky=tk.W) self.entry_numbers = tk.Entry(self.master) self.entry_numbers.grid(row=0, column=1, padx=10, pady=10, sticky=tk.W) self.generate_button = tk.Button(self.master, text="Generate Barcodes", command=self.generate_barcodes) self.generate_button.grid(row=1, column=0, columnspan=2, pady=10) def generate_barcodes(self): numbers = self.entry_numbers.get().split(',') folder_path = filedialog.askdirectory() for number in numbers: number = number.strip() if number: pdf_filename = f"{folder_path}/barcode_{number}_code128.pdf" self.generate_and_save_barcode_to_pdf(pdf_filename, number) messagebox.showinfo("Success", "Barcodes generated successfully.") def generate_and_save_barcode_to_pdf(self, pdf_filename, number): c = canvas.Canvas(pdf_filename, pagesize=letter) my_code = Code128(number, writer=ImageWriter()) barcode_image = my_code.render() c.drawInlineImage(barcode_image, 100, 500, width=200, height=100) c.save() if __name__ == "__main__": root = tk.Tk() app = BarcodeGeneratorApp(root) root.mainloop()
- 报错堆栈:
Exception in Tkinter callback Traceback (most recent call last): File "tkinter\__init__.py", line 1948, in __call__ File "Fack.py", line 31, in generate_barcodes File "Fack.py", line 38, in generate_and_save_barcode_to_pdf File "barcode\codex.py", line 255, in render File "barcode\base.py", line 100, in render File "barcode\writer.py", line 269, in render File "barcode\writer.py", line 440, in _paint_text File "PIL\ImageFont.py", line 791, in truetype File "PIL\ImageFont.py", line 788, in freetype File "PIL\ImageFont.py", line 226, in __init__ OSError: cannot open resource
问题原因
报错根源是python-barcode库默认使用的系统字体在打包后无法被PyInstaller识别并打包,导致PIL加载字体资源失败。
解决步骤
步骤1:获取并复制默认字体文件
- 本地运行以下代码,查看
python-barcode默认使用的字体路径:
from barcode.writer import ImageWriter writer = ImageWriter() print(writer.font_path)
通常默认字体为arial.ttf或DejaVuSans.ttf。
2. 找到对应字体文件,复制到项目根目录。
步骤2:修改代码手动指定字体路径
修改generate_and_save_barcode_to_pdf方法,初始化ImageWriter时显式指定字体路径:
import sys import os def get_font_path(): if hasattr(sys, '_MEIPASS'): # 打包后运行时的临时目录路径 return os.path.join(sys._MEIPASS, 'arial.ttf') else: # 本地运行时的字体路径 return 'arial.ttf' # 修改原方法 def generate_and_save_barcode_to_pdf(self, pdf_filename, number): c = canvas.Canvas(pdf_filename, pagesize=letter) writer = ImageWriter() writer.font_path = get_font_path() my_code = Code128(number, writer=writer) barcode_image = my_code.render() c.drawInlineImage(barcode_image, 100, 500, width=200, height=100) c.save()
步骤3:PyInstaller打包时包含字体文件
使用以下命令打包(Windows系统用;分隔路径,Linux/macOS用:):
pyinstaller --onefile --add-data "arial.ttf;." your_script_name.py
内容的提问来源于stack exchange,提问作者Dwayne
相关产品推荐
相关产品推荐

