有没有办法刷新已重新配置小部件的 tkinter 框架?

Is there a way to refresh a tkinter frame in which widgets have been reconfigured?

我想允许用户配置应用程序的外观(背景颜色、字体、字体大小和颜色、按钮颜色等)。我已将所有默认设置保存到一个配置文件中,程序解释该文件并将其保存到 class 内的变量中,以便在函数之间轻松访问。现在,我可以将用户所做的更改保存到配置文件中,这些更改将在用户关闭并重新打开应用程序时反映出来,但我希望这些更改是即时的,所以我尝试了这样的操作:

import tkinter as tk

class SetColor:
    def __init__(self, color):
        self.color = 'green'
current = SetColor('green')

root = tk.Tk()

lbl_color = tk.Label(root, text='Choose button color')
lbl_color.grid(row=0, column=0, pady=5, padx=2)

btn_red = tk.Button(root, text='Red', bg=current.color, command=lambda:update_color('red'))
btn_red.grid(row=0, column=1, pady=5, padx=2)

btn_green = tk.Button(root, text='Green', bg=current.color, command=lambda:update_color('green'))
btn_green.grid(row=0, column=2, pady=5, padx=2)

btn_blue = tk.Button(root, text='Blue', bg=current.color, command=lambda:update_color('blue'))
btn_blue.grid(row=0, column=3, pady=5, padx=2)

def update_color(color):
    current.color = color
    #THIS is where I'm wondering if there's a way to refresh without individually updating each widget as I've done below
    btn_red.config(bg=current.color)
    btn_green.config(bg=current.color)
    btn_blue.config(bg=current.color)       
    
root.mainloop()

这确实有效,但在我的实际应用程序中,需要更新的小部件比这个 ^ 示例中多得多。所以我觉得我遗漏了一些东西或者以错误的方式处理了这件事。非常感谢任何帮助:)

最好的办法是将按钮存储在列表中并循环遍历该列表。这样你就可以分开不同的按钮。但是,如果您确定要更改每个按钮的颜色,您可以这样做:for widget in root.winfo_children(): if isinstance(widget, tk.Button): widget.config(bg=current.color)

@Maarten 的回答非常适合 tkinter 按钮。 在这种情况下可以使用另一个使用 ttk.Button 的选项

创建具有自定义样式的按钮对象
btn_green = ttk.Button(root, text='Green', style="color.TButton", command=lambda: update_color('green'))
创建样式对象
style = ttk.Style()
style.theme_use("default")
设置样式
style.configure('color.TButton', background=current.color)
# Activate is when you mouse over the button.
style.map('color.TButton', background=[('active', current.color)])
完整示例:
import tkinter as tk
from tkinter import ttk


class SetColor:
    def __init__(self, color):
        self.color = 'green'


def update_color(color):
    current.color = color
    # Let's set the style
    # naming that style variable as color.TButton
    # NOTE: .TButton is important, you can add any other pretix though
    style.configure('color.TButton', background=current.color)

    # Activate is when you mouse over the button.
    style.map('color.TButton', background=[('active', current.color)])


current = SetColor('green')

root = tk.Tk()


# Create style Object
style = ttk.Style()
# Setting theme to default (built in themes can be found https://wiki.tcl-lang.org/page/List+of+ttk+Themes)
style.theme_use("default")

lbl_color = ttk.Label(root, text='Choose button color')
lbl_color.grid(row=0, column=0, pady=5, padx=2)

btn_red = ttk.Button(root, text='Red', style="color.TButton", command=lambda: update_color('red'))
btn_red.grid(row=0, column=1, pady=5, padx=2)

btn_green = ttk.Button(root, text='Green', style="color.TButton", command=lambda: update_color('green'))
btn_green.grid(row=0, column=2, pady=5, padx=2)

btn_blue = ttk.Button(root, text='Blue', style="color.TButton", command=lambda: update_color('blue'))
btn_blue.grid(row=0, column=3, pady=5, padx=2)

update_color(current.color)

root.mainloop()

有更多 ttk 风格的选项可供选择。

看看

Python ttk Style

ttk Themes