我在Tkinter中创建一个界面,我需要自定义字体。不仅仅是说,Helvetica只有一定的尺寸或者其他什么,而是字体,而不是通常在任何给定平台上可用的字体。这将是程序作为图像文件或(优选地)Truetype字体文件或类似文件保存的东西。我不想在每台要使用该程序的机器上安装所需的字体,我只是想在同一目录中随身携带它们。
tkFont模块看起来应该做这样的事情,但是我无法看到运行该程序的系统通常无法访问的字体的文件名。 在此先感谢您的帮助。
答案 0 :(得分:7)
没有办法将外部字体文件加载到Tkinter而不诉诸平台特定的黑客攻击。 Tkinter没有任何内置支持它。
答案 1 :(得分:7)
(至少在Windows上)
使这项工作的关键代码是以下功能:
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
,{{ 1}},.fot
,.otf
,.mmm
或.pfb
),您可以像任何其他已安装的字体.pfm
一样加载字体。并在任何你喜欢的地方使用它。 [有关详细信息,请参阅MSDN]
这里最大的警告是字体的姓氏不一定是文件的名称;它嵌入在字体数据中。而不是试图解析名称,可能更容易在字体浏览器GUI中查找并硬编码到您的应用程序中。 编辑:或者,根据下面的patthoyt评论,在tkFont.Font(family=XXX, ...)
中查找(作为最后一项,或者更强大的是,通过比较加载字体之前和之后的系列列表)。
我在digsby(license)中找到了此功能;如果要在程序完成执行之前删除字体,那么在那里定义了tkFont.families()
函数。 (您也可以依靠unloadfont
设置在程序结束时卸载字体。)
对于任何感兴趣的人,here是几年前关于[TCLCORE]的这个主题的讨论。还有一些背景:fonts on MSDN
答案 2 :(得分:7)
这在Windows上对我有用,但在Linux上似乎不起作用:
import pyglet,tkinter
pyglet.font.add_file('file.ttf')
root = tkinter.Tk()
MyLabel = tkinter.Label(root,text="test",font=('font name',25))
MyLabel.pack()
root.mainloop()
答案 3 :(得分:2)
我找到this discussion,其中介绍了如何使用一行文字作为图像,并使用PIL将其放入窗口。这可能是一个解决方案。
我找不到使用tkFont导入tkFont man page中的捆绑字体的方法。
答案 4 :(得分:0)
这对我来说是一个简单的解决方案:
import pyglet, tkinter
pyglet.font.add_file("your font path here")
#then you can use the font as you would normally
答案 5 :(得分:0)
对于Linux,我能够将拥有的otf
字体文件安装到系统字体目录中:
mkdir /usr/share/fonts/opentype/my_fonts_name
cp ~/Downloads/my_fonts_name.otf /usr/share/fonts/opentype/my_fonts_name/
我发现此主目录有效,并最终改为使用它:
mkdir ~/.fonts/
cp ~/Downloads/my_fonts_name.otf ~/.fonts/
无论哪种情况,我都可以使用字体名称的字符串加载(如所有tkinter文档所示):
# unshown code
self.canvas = tk.Canvas(self.data_frame, background="black")
self.canvas.create_text(event.x, event.y, text=t, tags='clicks',
fill='firebrick1',
font=("My Fonts Name", 22))