我正在使用Tkinter和ttk在Python中创建GUI。我想为用户可以配置的UI分别设置两个主题。其中一个选项是使用以下代码调用的vista
主题:
from tkinter import Tk
from tkinter.ttk import Style
root = Tk()
root.style = Style()
root.style.theme_use('vista')
另一个选项是black
主题,使用:
from tkinter import Tk
from ttkthemes import ThemedStyle
root = Tk()
root.style = ThemedStyle()
root.style.theme_use('black')
我遇到了一些问题,因为我希望用户能够在程序运行时切换主题。单独应用这些主题(即应用主题,关闭程序并在启动时应用其他主题)工作正常。在从root.style = ThemedStyle()
主题转换为root.style = Style()
主题后,在代码中稍后的某个地方调用vista
后跟black
时,我开始遇到问题:
if self.ui_theme == 'Dark':
self.root.style = ThemedStyle()
theme = 'black'
self.root.tk_setPalette(background='#2f3136')
else:
self.root.style = Style()
theme = 'vista'
self.root.tk_setPalette(background='#f0f0f0')
self.root.style.theme_use(theme)
最重要的是,从black
转到vista
再返回black
会再次导致以下错误:
error reading package index file C:/Python34/Lib/site-packages/ttkthemes/themes/pkgIndex.tcl: Theme plastik already exists
我认为在同一个实例中两次调用self.root.style = ThemedStyle()
时会发生这种情况。
有没有办法绕过这个而不强迫用户在应用新主题时重启应用程序?提前谢谢。
答案 0 :(得分:2)
在开始时仅创建一次Style()
和ThemeStyle()
并分配给变量。
稍后将变量分配给root.style
。
from tkinter import Tk
from tkinter.ttk import Style, Button
from ttkthemes import ThemedStyle
def style_1():
print('winxpblue')
root.style = s
root.style.theme_use('winxpblue')
def style_2():
print('black')
root.style = t
root.style.theme_use('black')
root = Tk()
s = Style()
t = ThemedStyle()
#print(s.theme_names())
#print(t.theme_names())
Button(root, text="winxpblue", command=style_1).pack()
Button(root, text="black", command=style_2).pack()
root.mainloop()
编辑:在Linux上测试后,我发现我不需要Style()
。我在ThemedStyle()
中拥有所有主题。也许在Windows / MacOS上,它的工作原理相同。
import tkinter as tk
from tkinter import ttk
import ttkthemes
root = tk.Tk()
root.style = ttkthemes.ThemedStyle()
for i, name in enumerate(sorted(root.style.theme_names())):
b = ttk.Button(root, text=name, command=lambda name=name:root.style.theme_use(name))
b.pack(fill='x')
root.mainloop()