我在 Tkinter 中制作界面,我需要自定义字体。不仅仅是,比如说,特定大小的 Helvetica 字体,而是任何给定平台上通常可用的字体以外的字体。这将作为图像文件或(最好)Truetype 字体文件或类似文件与程序一起保存。我不想在每台要使用该程序的机器上都安装所需的字体,我只想将它们与程序放在同一目录中。
tkFont 模块看起来应该做这样的事情,但我看不出它会在哪里为运行该程序的系统通常无法访问的字体获取文件名。 预先感谢您的帮助。
最佳答案
有一种方法可以将外部字体导入 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)
使用字体文件的路径调用 loadfont
后(可以是 .fon
、.fnt
、 中的任何一个) .ttf
, .ttc
, .fot
, .otf
, .mmm
, .pfb
或 .pfm
),您可以像加载任何其他已安装的字体一样加载字体 tkFont.Font(family=XXX, ...)
。并在任何你喜欢的地方使用它。 [参见MSDN获取更多信息]
这里最大的警告是字体的姓氏不一定是文件名;它嵌入在字体数据中。与其尝试解析名称,不如在字体浏览器 GUI 中查找它并将其硬编码到您的应用程序中可能会更容易。 编辑:或者,根据下面 patthoyt 的评论,在 tkFont.families()
中查找(作为最后一项,或者更稳健地,通过比较之前的家族列表加载字体后)。
我在 digsby 中找到了这个函数( license );如果你想在程序完成执行之前删除字体,这里定义了一个 unloadfont
函数。 (您也可以仅依靠 private
设置在程序结束时卸载字体。)
任何有兴趣的人,here是几年前在【TCLCORE】上关于这个话题的讨论。更多背景:fonts on MSDN
关于python - Tkinter 中真正的自定义字体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11993290/