Python Tkinter 调整所有 ttkbootstrap 或 ttk 按钮的填充,以特定样式应用于所有主题
我想要改变所有按钮的内边距,特别是那种叫“danger”的样式。但是奇怪的是,这个改动只在当前主题下有效,换个主题后,按钮的内边距又变回默认的了。你可以通过运行以下代码并切换主题来看到这个问题...
import tkinter as tk
from tkinter import ttk
import ttkbootstrap as tb
def change_theme(theme, style): style.theme_use(theme.lower().replace(" ", ""))
def display_text(label_text, entry_text): label_text.set(entry_text.get())
def setup_ui(style):
root = style.master
danger = tb.Style()
danger.configure('danger.TButton', padding=0) # Why does this only apply to the first theme?
theme_names_titlecase = [name.replace('_', ' ').title() for name in style.theme_names() if name.lower() in ['darkly', 'simplex']]
default_theme = 'darkly'
current_theme = tk.StringVar(value=default_theme.capitalize())
theme_combo = ttk.Combobox(root, textvariable=current_theme, values=theme_names_titlecase, width=50)
theme_combo.pack(pady=0, side=tk.TOP)
theme_combo.bind("<<ComboboxSelected>>", lambda e: change_theme(current_theme.get(), style))
tb.Button(root, text='Text', bootstyle='danger.TButton').pack(side=tk.TOP, padx=0, pady=0)
tb.Button(root, text='Text', bootstyle='info.TButton').pack(side=tk.TOP, padx=0, pady=0)
return root
if __name__ == "__main__":
default_theme = 'darkly'
style = tb.Style(theme=default_theme)
root = setup_ui(style)
root.mainloop()
我想知道的是:
- 为什么我对“danger.TButton”的修改只在当前主题下有效?
- 有没有办法让所有“danger.TButton”的内边距都没有,不管主题是什么?
注意:使用所有ttk小部件和样式的结果都是一样的,所以这个问题和ttk有关,而不是特别针对ttkbootstrap。
非常感谢。
2 个回答
2
这个样式显然只在程序启动时使用的主题上生效。
所以当你把主题换成非默认的主题时,就需要重新调整边距。在这个例子中,为了解决这个问题,我需要修改'change_theme'这个函数。
def change_theme(theme, style):
style.theme_use(theme.lower().replace(" ", ""))
style.configure('danger.TButton', padding=0)
这样一来,每次换新主题的时候,边距的调整就会重新应用上。
0
主要原因在于这部分内容,以及在 setup_ui()
函数中配置 tb.Style()
。这意味着你为 danger.TButton
设置的配置只和 tb.Style()
的这个实例有关。所以,当你尝试更改主题时,ttkbootstrap
会在内部创建一个新的 tb.Style()
实例,而你的自定义配置不会被带到这个新实例上。
danger = tb.Style()
danger.configure('danger.TButton', padding=0) # Why does this only apply to the first theme?
通过直接在 tb.Style()
的主实例上配置 danger.TButton
,你的自定义配置就会在所有主题中一致地应用。以下是你代码的解决方案:
import tkinter as tk
from tkinter import ttk
import ttkbootstrap as tb
def change_theme(theme, style):style.theme_use(theme.lower().replace(" ", ""))
def display_text(label_text, entry_text):label_text.set(entry_text.get())
def setup_ui(style):
root = style.master
theme_names_titlecase = [name.replace('_', ' ').title() for name in style.theme_names() if name.lower() in ['darkly', 'simplex']]
default_theme = 'darkly'
current_theme = tk.StringVar(value=default_theme.capitalize())
theme_combo = ttk.Combobox(root, textvariable=current_theme, values=theme_names_titlecase, width=50)
theme_combo.pack(pady=0, side=tk.TOP)
theme_combo.bind("<<ComboboxSelected>>", lambda e: change_theme(current_theme.get(), style))
tb.Button(root, text='Text', bootstyle='danger.TButton').pack(side=tk.TOP, padx=0, pady=0)
tb.Button(root, text='Text', bootstyle='info.TButton').pack(side=tk.TOP, padx=0, pady=0)
return root
if __name__ == "__main__":
default_theme = 'darkly'
style = tb.Style(theme=default_theme)
style.configure('danger.TButton', padding=0) # Why does this only apply to the first theme?
root = setup_ui(style)
root.mainloop()