如何在Tkinter所有窗口中应用Sun Valley主题
Tkinter中Sun Valley主题无法应用到第二个窗口的解决方案
在Tkinter的设计规范里,一个应用程序只能存在一个tk.Tk实例(主窗口),所有其他窗口都应该用tk.Toplevel来创建。你的代码中Test和Main都继承自tk.Tk,相当于启动了两个独立的Tkinter运行环境,主题只会绑定到第一个tk.Tk实例,第二个实例无法共享主题配置,这就是问题根源。
修改后的代码
import tkinter as tk from tkinter import ttk import sv_ttk class Test(tk.Tk): def __init__(self): super().__init__() sv_ttk.use_dark_theme() self.geometry('250x150') self.title("Test") self.resizable(0,0) self.columnconfigure(0, weight=1) self.columnconfigure(1, weight=3) # 分开创建与布局,避免变量被赋值为None testButton = ttk.Button(self, text="Press me!", command=self.newWindow) testButton.grid(column=0, row=3, sticky=tk.E, padx=5, pady=5) def newWindow(self): # 基于主窗口创建Toplevel子窗口 self.main_window = Main(self) # 隐藏主窗口而非销毁(销毁主窗口会直接终止应用) self.withdraw() class Main(tk.Toplevel): def __init__(self, parent): super().__init__(parent) # 无需重复调用主题方法,会自动继承主窗口的主题配置 self.geometry('1200x800') self.title("Main") self.resizable(0,0) self.columnconfigure(0, weight=1) self.columnconfigure(1, weight=1) self.test = ttk.Checkbutton(self, text="testing", style="Toggle.TButton") self.test.grid(column=0, row=0, sticky=tk.W, padx=5, pady=5) # 绑定关闭事件,关闭子窗口时恢复主窗口 self.protocol("WM_DELETE_WINDOW", self.on_close) def on_close(self): self.master.deiconify() self.destroy() if __name__ =="__main__": app = Test() app.mainloop()
关键修改说明
- 将
Main类改为继承tk.Toplevel,并传入主窗口作为父组件,使其共享主窗口的主题配置 - 移除
Main中的sv_ttk.use_dark_theme()调用,主题会自动从主窗口继承 - 用
withdraw()隐藏主窗口替代destroy(),避免直接终止整个应用 - 添加子窗口关闭事件处理,恢复主窗口,提升交互体验
- 修正按钮创建时直接链式调用
grid导致变量为None的常见问题
内容的提问来源于stack exchange,提问作者OttoLuck
相关产品推荐
相关产品推荐

