我可以在一个Tkinter(tk.Tk)根窗口中使用两个不同的TTK主题吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我可以在一个Tkinter(tk.Tk)根窗口中使用两个不同的TTK主题吗?相关的知识,希望对你有一定的参考价值。
这个问题涉及Python和Tkinter。
我想同时使用两个不同的ttk主题,例如'蛤蜊'和'vista'在一个Tkinter窗口中。所以我写了这个:
import tkinter as tk
import tkinter.ttk as ttk
class GUI(tk.Tk):
def __init__(self):
super().__init__()
Button_v1()
Button_v2()
class Button_v1(ttk.Button):
def __init__(self, default_text="Test"):
super().__init__(text=default_text)
s = ttk.Style()
s.theme_use('clam')
s.configure(self.winfo_class(), foreground='blue')
self.pack()
class Button_v2(ttk.Button):
def __init__(self, default_text="Test2"):
super().__init__(text=default_text)
s2 = ttk.Style()
s2.theme_use('vista')
s2.configure(self.winfo_class(), foreground='red')
self.pack()
GUI().mainloop()
但是,代码加载:
- 我希望第一个Button的前景为蓝色,第二个Button的前景为红色,并且要使用两个单独的主题。
- 相反,两个按钮都有一个红色前景,并且都应用相同的主题。
是否可以在一个Tkinter程序中使用两个单独的ttk主题?
不,这是不可能的,因为theme
在这方面具有全球意义。您可以将theme
表示为小部件的一组样式(for widget layout elements, actually),您可以更改样式和/或创建新样式,但是当时不能使用多个主题,因为小部件的布局在很大程度上取决于它。
当你调用theme_use('theme_name')
tkinter重建所有小部件的布局和redraws your entire application时,你可以轻松地检查这一点,感谢<<ThemeChanged>>
虚拟事件。
这是一个片段。您将看到由每个按钮和root本身引起的三个打印件。
try:
import tkinter as tk
import tkinter.ttk as ttk
except ImportError:
import Tkinter as tk
import ttk
class GUI(tk.Tk):
def __init__(self):
super().__init__()
self.bind('<<ThemeChanged>>', lambda event: print('theme changed in root and across all widgets!'))
Button_v1()
Button_v2()
class Button_v1(ttk.Button):
def __init__(self, default_text="Test"):
super().__init__(text=default_text)
s = ttk.Style()
s.theme_use('clam')
s.configure(self.winfo_class(), foreground='blue')
self.pack()
class Button_v2(ttk.Button):
def __init__(self, default_text="Test2"):
super().__init__(text=default_text)
s2 = ttk.Style()
s2.theme_use('vista')
s2.configure(self.winfo_class(), foreground='red')
self.pack()
GUI().mainloop()
如果每个按钮需要不同的前景 - 为每个按钮需要then create a new style
并使用style
参数:
这是另一个片段:
try:
import tkinter as tk
import tkinter.ttk as ttk
except ImportError:
import Tkinter as tk
import ttk
class GUI(tk.Tk):
def __init__(self):
super().__init__()
s = ttk.Style()
s.configure('blue.TButton', foreground='blue')
s.configure('red.TButton', foreground='red')
Button_v1()
Button_v2()
class Button_v1(ttk.Button):
def __init__(self, default_text="Test"):
super().__init__(text=default_text, style='blue.TButton')
self.pack()
class Button_v2(ttk.Button):
def __init__(self, default_text="Test2"):
super().__init__(text=default_text, style='red.TButton')
self.pack()
GUI().mainloop()
不,不可能同时使用两个不同的主题。
从规范文档[1]为theme_use
方法的基础功能(重点由我添加):
没有参数,结果是当前主题的名称。否则,此命令将当前主题设置为themeName,并刷新所有小部件。
这是一个简单的示例,展示了如何动态切换主题:
# python 2
import Tkinter as tk
import ttk
# python 3
#import tkinter as tk
#import tkinter.ttk as ttk
def switch_theme(theme):
style = ttk.Style()
style.theme_use(theme)
root = tk.Tk()
style = ttk.Style()
for theme in style.theme_names():
button = ttk.Button(root, text=theme,
command=lambda theme=theme: switch_theme(theme))
button.pack(side="top", padx=4, pady=4)
root.mainloop()
不可以。您不能使用两个不同的主题。但是,您可以创建一个样式:
style = ttk.Style()
style.configure("BW.TLabel", foreground="black", background="white")
l1 = ttk.Label(text="Test", style="BW.TLabel")
l2 = ttk.Label(text="Test", style="BW.TLabel")
您可以为其他窗口小部件创建另一种样式
以上是关于我可以在一个Tkinter(tk.Tk)根窗口中使用两个不同的TTK主题吗?的主要内容,如果未能解决你的问题,请参考以下文章