在Tkinter中完全更改不同小部件的颜色

时间:2020-05-26 21:27:25

标签: python tkinter colors

当用户单击Entry小部件时,我想将不同小部件的不同配置颜色全部更改为相同的颜色。

我创建了一个函数change_color(color),其中所有小部件都已配置为使用作为参数传递的颜色。

问题在于代码中包含许多小部件,我必须手动将每个小部件添加到函数中以使其保持更新。我无法使用列表,因为某些小部件的选项不同,例如:更改输入小部件的前景,标签的背景等等。请告诉我是否有更好的方法。


这是我的程序的一个小例子。我的主要代码很长,不适合在此处发布。

import tkinter as tk

def change_color(color):
    "Change color of widgets."
    window.config(bg=color)
    user_label.config(bg=color)
    pass_label.config(bg=color)
    user_entry.config(highlightbackground=color)
    pass_entry.config(highlightbackground=color)
    user_entry.config(fg=color, insertbackground=color)
    pass_entry.config(fg=color, insertbackground=color)

window = tk.Tk()
# username
user_label = tk.Label(window, text='Username')
user_entry = tk.Entry(window, bg='black')
# password
pass_label = tk.Label(window, text='Password')
pass_entry = tk.Entry(window, bg='black')
user_label.grid(row=0, column=0)
user_entry.grid(row=0, column=1)
pass_label.grid(row=1, column=0)
pass_entry.grid(row=1, column=1)
# changes color
user_entry.bind("<1>", lambda _: change_color("#99c9ff"))
pass_entry.bind("<1>", lambda _: change_color("#ffaf99"))
window.mainloop()

我希望您能从此示例中获得启发。如果不清楚,请在评论部分询问我。

3 个答案:

答案 0 :(得分:1)

您可以使用winfo_children()递归浏览所有小部件:

def change_color(color, container=None):
    if container is None:
        container = window  # set to root window
    container.config(bg=color)
    for child in container.winfo_children():
        if child.winfo_children():
            # child has children, go through its children
            change_color(color, child)
        elif type(child) is tk.Label:
            child.config(bg=color)
        elif type(child) is tk.Entry:
            child.config(highlightbackground=color)
            child.config(fg=color, insertbackground=color)
        # check for other widget types ...

答案 1 :(得分:1)

如果可以在程序中使用外部模块,请安装tkmacosx模块。通过使用pip命令,您可以像这样安装它。

pip install tkmacosx

当将

ColorVar 分配给带有参数textvariable=stringvar的标签时,其作用就像 StringVar 变量一样。

使用 ColorVar ,您甚至不需要任何功能即可更改小部件的颜色,只需要做colorvar.set(color),并将所有小部件分配给colorvar会改变他们的颜色。您还可以使用多个ColorVar()将不同颜色的组与不同组的小部件进行分组。

...
color1 = ColorVar(value='blue')
color2 = ColorVar(value='yellow')

tk.Label(root, text='Color1', fg=color1).pack()
tk.Label(root, text='Color2', fg=color2).pack()

color1.set('red')
color2.set('pink')
...

这是您的示例代码。

import tkinter as tk
import tkmacosx as tkm

window = tk.Tk()
colorvar1 = tkm.ColorVar()
window.config(bg=colorvar1)

# username
user_label = tk.Label(window, text='Username', bg=colorvar1)
user_entry = tk.Entry(window, bg='black', fg=colorvar1, 
                      insertbackground=colorvar1, highlightbackground=colorvar1)
# password
pass_label = tk.Label(window, text='Password', bg=colorvar1)
pass_entry = tk.Entry(window, bg='black', fg=colorvar1, 
                      insertbackground=colorvar1, highlightbackground=colorvar1)

user_label.grid(row=0, column=0)
user_entry.grid(row=0, column=1)
pass_label.grid(row=1, column=0)
pass_entry.grid(row=1, column=1)
# changes color
user_entry.bind("<1>", lambda _: colorvar1.set("#99c9ff"))
pass_entry.bind("<1>", lambda _: colorvar1.set("#ffaf99"))
window.mainloop()

答案 2 :(得分:0)

这是一种实现方法。

import tkinter as tk

def change_color(color):
    "Change color of widgets."

    for wdg in window.children:
        wdg = window.nametowidget(wdg)
        if isinstance(wdg, tk.Label):
            wdg.config(bg=color)
        elif isinstance(wdg, tk.Entry):
            wdg.config(fg=color, insertbackground=color, highlightbackground=color)


window = tk.Tk()
# username
user_label = tk.Label(window, text='Username')
user_entry = tk.Entry(window, bg='black')
# password
pass_label = tk.Label(window, text='Password')
pass_entry = tk.Entry(window, bg='black')
user_label.grid(row=0, column=0)
user_entry.grid(row=0, column=1)
pass_label.grid(row=1, column=0)
pass_entry.grid(row=1, column=1)
# changes color
user_entry.bind("<1>", lambda _: change_color("#99c9ff"))
pass_entry.bind("<1>", lambda _: change_color("#ffaf99"))

window.mai