You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter多窗口跳转时子窗口Form2自定义字体不生效无报错如何解决

问题根因
  • Tkinter不支持多tk.Tk()实例的资源共享:每个tk.Tk()实例对应独立的Tcl解释器运行上下文,自定义字体、图片等资源默认绑定到创建资源时活跃的tk.Tk实例,无法跨实例生效。单独运行Form2时整个进程只有一个tk.Tk实例,字体可以正常识别;通过Form1触发打开Form2时,Form2作为第二个tk.Tk实例,其内部创建的字体资源默认绑定到已存在的Form1实例上下文,Form2自身的上下文无法识别该字体,就会静默降级为系统默认字体,不会抛出报错。
  • 重复调用mainloop()不符合规范:一个Tkinter应用全局只需要执行一次mainloop()处理全局事件,在按钮点击事件里第二次调用mainloop()也会引发资源加载、事件处理的异常。
修复方案

核心修改逻辑是将子窗口Form2的继承对象从tk.Tk改为专门用于子窗口的tk.Toplevel类,Toplevel会共享主窗口的Tcl上下文,资源可以通用,同时移除多余的mainloop()调用。

修改后的可运行代码如下:

from tkinter.ttk import *
import tkinter as tk
from tkinter import messagebox
from tkinter import *
import tkinter.font as tkFont

# 改为继承tk.Toplevel而非tk.Tk
class Form2(tk.Toplevel):
    def __init__(self):
        super().__init__()  

        self.title("Form2")
        self.geometry("350x600")
        self.resizable(0, 0)

        self.label = tk.Label(self, text='form2',
                          font=tkFont.Font(family="Roboto", size=18))
        self.label.pack()


class Form1(tk.Tk):
    def __init__(self):
        super().__init__()  

        self.title("Form1")
        self.geometry("350x600")
        self.resizable(0, 0)

        self.label = tk.Label(self, text='form1',
                          font=tkFont.Font(family="Roboto", size=18))
        self.label.pack()

        self.button: object = tk.Button(self, overrelief="solid", width=10, height=2,
                                    repeatdelay=1000, repeatinterval=100,
                                    text="Preferences",
                                    font=tkFont.Font(family="Roboto", size=9),
                                    command=lambda: self.button_clicked())
        self.button.pack()

    def button_clicked(self):
        # 直接创建Form2实例即可,不需要调用mainloop
        form2 = Form2()


if __name__ == '__main__':
    form1 = Form1()
    form1.mainloop()
补充说明

如果确实有特殊场景需要使用多tk.Tk()实例,可以在创建字体时显式指定字体绑定的master为当前窗口,例如Form2中创建字体的代码改为tkFont.Font(self, family="Roboto", size=18),手动绑定到Form2实例即可生效,但这种方案仍然不推荐,多Tk实例会引发很多隐性问题,优先使用Toplevel实现多窗口需求。

内容的提问来源于stack exchange,提问作者freshcodeman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 01:36:03