【问题标题】:Why can't I define (and save) Tkinter fonts inside a function?为什么我不能在函数中定义(和保存)Tkinter 字体?
【发布时间】:2014-10-29 13:24:08
【问题描述】:

在函数内部和脚本主体中定义字体似乎表现不同,我似乎无法弄清楚它应该如何工作。

例如,本例中的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()

main_frame.pack() 之前的第一个版本中打印出tkFont.names(),将自定义字体列为font<id>,但在第二个版本中打印相同的内容不会列出define_styles 函数之外的自定义字体。我必须做一些特别的事情来拯救他们吗?

为什么我不能将该代码放入函数中?我是否从根本上误解了字体应该如何使用? tkFont 似乎有某种字体注册表,为什么我的没有留下来?

【问题讨论】:

    标签: python python-2.7 tkinter ttk


    【解决方案1】:

    我没有证据支持这一点,但我相信一旦define_styles 结束,Python 就会对您的large Font 对象进行垃圾收集。这是因为没有纯 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
    

    结果:

    【讨论】:

    • 这是有道理的,并且确实解决了这个例子(以及首先引发这个问题的更大的程序),如果有点不满意的话。那么这是一个错误吗?它可能缺少文档,但从现在到永恒,我可能会为 tkinter 填写缺少的文档错误。
    • 我认为它处于“错误”和“复杂系统的惊人交互”之间的灰色地带。如果不需要这种手动参考保存,我会喜欢它,但据我所知,开发人员有一个很好的理由这样做。
    • 今天刚遇到这个怪癖——Python 3.7 仍然如此。它确实会被垃圾收集,并且在Font__del__ 方法中,还有一个对Tk 的调用以将其从其内部字体清单中删除。
    猜你喜欢
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 2015-07-10
    • 1970-01-01
    • 1970-01-01
    • 2016-03-09
    • 2021-05-12
    相关资源
    最近更新 更多