Tkinter 中真正的自定义字体

新手上路,请多包涵

我在 Tkinter 中制作界面,我需要自定义字体。不仅仅是,比如说,特定大小的 Helvetica 字体,而是任何给定平台上通常可用的字体以外的字体。这将作为图像文件或(最好)Truetype 字体文件或类似文件与程序一起保存。我不想在每台要使用该程序的机器上都安装所需的字体,我只想将它们与程序放在同一目录中。

tkFont 模块看起来应该做这样的事情,但我看不到运行该程序的系统通常无法访问的字体的文件名在哪里。在此先感谢您的帮助。

原文由 Verdigriss 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

我发现 了这个讨论,其中介绍了如何将一行文本用作图像并使用 PIL 将其放入窗口中。这可能是一个解决方案。

我在 tkFont 手册页 中找不到使用 tkFont 导入捆绑字体的方法。

原文由 Kevin London 发布,翻译遵循 CC BY-SA 3.0 许可协议

有一种方法可以将外部字体导入 Windows 上的 Tkinter。

使这项工作起作用的关键代码是以下函数:

 from ctypes import windll, byref, create_unicode_buffer, create_string_buffer
FR_PRIVATE  = 0x10
FR_NOT_ENUM = 0x20

def loadfont(fontpath, private=True, enumerable=False):
    '''
    Makes fonts located in file `fontpath` available to the font system.

    `private`     if True, other processes cannot see this font, and this
                  font will be unloaded when the process dies
    `enumerable`  if True, this font will appear when enumerating fonts

    See https://msdn.microsoft.com/en-us/library/dd183327(VS.85).aspx

    '''
    # This function was taken from
    # https://github.com/ifwe/digsby/blob/f5fe00244744aa131e07f09348d10563f3d8fa99/digsby/src/gui/native/win/winfonts.py#L15
    # This function is written for Python 2.x. For 3.x, you
    # have to convert the isinstance checks to bytes and str
    if isinstance(fontpath, str):
        pathbuf = create_string_buffer(fontpath)
        AddFontResourceEx = windll.gdi32.AddFontResourceExA
    elif isinstance(fontpath, unicode):
        pathbuf = create_unicode_buffer(fontpath)
        AddFontResourceEx = windll.gdi32.AddFontResourceExW
    else:
        raise TypeError('fontpath must be of type str or unicode')

    flags = (FR_PRIVATE if private else 0) | (FR_NOT_ENUM if not enumerable else 0)
    numFontsAdded = AddFontResourceEx(byref(pathbuf), flags, 0)
    return bool(numFontsAdded)

After you call loadfont with the path to your font file (which can be any of .fon , .fnt , .ttf , .ttc , .fot , .otf , .mmm , .pfb , or .pfm ), you can load字体与任何其他已安装的字体一样 tkFont.Font(family=XXX, ...) 。并在任何你喜欢的地方使用它。 [有关详细信息,请参阅 MSDN ]

这里最大的警告是字体的姓氏不一定是文件的名称;它嵌入在字体数据中。与其尝试解析名称,不如在字体浏览器 GUI 中查找它并将其硬编码到您的应用程序中可能会更容易。 编辑:或者,根据下面 patthoyt 的评论,在 tkFont.families() 中查找(作为最后一项,或者更稳健地,通过比较加载字体前后的系列列表)。

我在 digsby ( license ) 中找到了这个函数;如果您想在程序完成执行之前删除字体,那么这里定义了一个 unloadfont 函数。 (您也可以仅依靠 private 设置在程序结束时卸载字体。)

对于任何感兴趣的人, 是几年前在 [TCLCORE] 上关于此主题的讨论。更多背景: MSDN 上的字体

原文由 Felipe 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏