在函数内部和脚本主体中定义字体似乎行为不同,我似乎无法弄清楚它应该如何工作。
例如,此示例中的Label
最终会按照预期使用更大的字体:
from Tkinter import *
from ttk import *
import tkFont
root = Tk()
default = tkFont.Font(root=root, name="TkTextFont", exists=True)
large = default.copy()
large.config(size=36)
style = Style(root)
style.configure("Large.TLabel", font=large)
root.title("Font Test")
main_frame = Frame(root)
Label(main_frame, text="Large Font", style="Large.TLabel").pack()
main_frame.pack()
root.mainloop()
但是,如果我尝试在函数内部定义样式,似乎字体会被删除或被垃圾收集,并且在窗口小部件需要使用它时不可用:
from Tkinter import *
from ttk import *
import tkFont
def define_styles(root):
default = tkFont.Font(root=root, name="TkTextFont", exists=True)
large = default.copy()
large.config(size=36)
style = Style(root)
style.configure("Large.TLabel", font=large)
root = Tk()
root.title("Font Test")
define_styles(root)
main_frame = Frame(root)
Label(main_frame, text="Large Font", style="Large.TLabel").grid(row=0, column=0)
main_frame.pack()
root.mainloop()
在tkFont.names()
将自定义字体列为main_frame.pack()
之前的第一个版本中打印font<id>
,但在第二个版本中打印相同版本不会列出define_styles
之外的自定义字体{1}}功能。我是否必须做一些特殊的事情来保存它们?
为什么我不能将该代码放入函数中?我是否从根本上误解了字体应该如何使用? tkFont
似乎有某种字体注册表,为什么我不能坚持下去?
答案 0 :(得分:6)
我没有证据支持这一点,但我相信一旦large
结束,你的define_styles
Font对象就会被Python收集。这是因为没有纯Python对象对它有任何引用,即使底层的Tcl实现仍在使用它。这个问题也困扰着Tkinter的PhotoImage
类。
解决方法是通过对对象进行长期引用来使对象保持活动状态。只需将其分配给root
对象上的任何旧属性,例如。
def define_styles(root):
default = tkFont.Font(root=root, name="TkTextFont", exists=True)
large = default.copy()
large.config(size=36)
style = Style(root)
style.configure("Large.TLabel", font=large)
root.myfont = large
结果: