使用 pyinstaller 在所有系统上保留字体

2024-04-19

我使用 tkinter 制作了一个 GUI。

我用 pyinstaller 创建了 onefile exe,但设置的字体(font = freesans.ttf)不适用于其他计算机。

我想我需要添加字体,但在与我类似的情况下,我不明白 pygame 或 pyqt 的答案。


这是在 Windows 上向 pyinstaller 可执行文件添加自定义字体的解决方案。您需要将字体路径添加到 pyinstaller 构建中--add-data所以它可以在MEI可执行文件使用的文件夹。

import ctypes
import sys
from pathlib import Path


def fetch_resource(rsrc_path):
    """Loads resources from the temp dir used by pyinstaller executables"""
    try:
        base_path = Path(sys._MEIPASS)
    except AttributeError:
        return rsrc_path  # not running as exe, just return the unaltered path
    else:
        return base_path.joinpath(rsrc_path)


def load_font(font_path, private=True, enumerable=False):
    """Add the font at 'font_path' as a Windows font resource"""
    FR_PRIVATE = 0x10
    FR_NOT_ENUM = 0x20
    flags = (FR_PRIVATE * int(private)) | (FR_NOT_ENUM * int(1 - enumerable))
    font_fetch = str(fetch_resource(font_path))
    path_buf = ctypes.create_unicode_buffer(font_fetch)
    add_font = ctypes.windll.gdi32.AddFontResource.ExW
    font_added = add_font(ctypes.byref(path_buf), flags, 0)
    return bool(font_added)  # True if the font was added successfully

然后在你的主Python文件中(或者你尝试使用freesans的任何地方),你可以像这样加载字体

import tkinter.font as font

custom_font = 'Freesans'  # check the name your system uses, I'm just gussing here

if custom_font not in font.families() and not load_font('<path/to/freesans.ttf>'):
    custom_font = 'Fallback font name here'  # if freesans can't be loaded...

一个重要的说明是我的fetch_resource函数可用于您需要的几乎任何应用程序资源,例如图标或图像。只需记住通过以下方式将它们添加到 pyinstaller--add-data,无论你在 Python 文件中使用它们,都可以通过以下方式获取它们的路径my_icon = fetch_resource('path/to/my_icon.ico')例如/这样,你可以使用my_icon当作为脚本运行或作为构建的 exe 运行时!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 pyinstaller 在所有系统上保留字体 的相关文章

随机推荐