更改特定(不是全部)ttk Entry 小部件中的背景颜色

问题描述 投票:0回答:1

在我的应用程序中,我有很多 Entry 小部件。我想更改小部件的背景颜色,以使用户清楚地知道他或她已在该小部件中输入了数据并且该数据已被应用程序捕获。使用 tk.Entry 使用 configure(background="color") 命令,这很容易。

但是,我还没有弄清楚如何使用样式为 ttk.Entry 做到这一点。非常欢迎提出建议。

在网上搜索后,我了解了如何使用样式来更改表单或框架中所有 ttkEntry 小部件的背景颜色。我找不到针对特定小部件执行此操作的任何信息。

python background-color
1个回答
0
投票

我已经为其编写了一个工作脚本,您可以在下面找到它。实际上,您应该定义 2 个 TTK 样式(一种用于空状态,另一种用于填充状态),并且如果 Entry 小部件(基本上是 StringVariable 对象的值)已填充或为空,则应使用回调函数更改样式。 (为了更好理解,我在测试代码中写了很多注释。)

from tkinter import *
from tkinter import ttk

root_window = Tk()

estyle = ttk.Style()
# Create a new element (Eg.: https://stackoverflow.com/questions/45389166/how-to-know-all-style-options-of-a-ttk-widget)
estyle.element_create("plain.field", "from", "clam")
# Create the layout for the style.
# It defines what the custom widget will look like.
estyle.layout(
    "EntryStyle.Empty",  # This name will be used for the style parameter
    [
        (
            "Entry.plain.field",
            {
                "children": [
                    (
                        "Entry.background",
                        {
                            "children": [
                                (
                                    "Entry.padding",
                                    {
                                        "children": [("Entry.textarea", {"sticky": "nswe"})],
                                        "sticky": "nswe",
                                    },
                                )
                            ],
                            "sticky": "nswe",
                        },
                    )
                ],
                "border": "2",
                "sticky": "nswe",
            },
        )
    ],
)
# Define another style for the "filled" state.
estyle.layout(
    "EntryStyle.Filled",
    [
        (
            "Entry.plain.field",
            {
                "children": [
                    (
                        "Entry.background",
                        {
                            "children": [
                                (
                                    "Entry.padding",
                                    {
                                        "children": [("Entry.textarea", {"sticky": "nswe"})],
                                        "sticky": "nswe",
                                    },
                                )
                            ],
                            "sticky": "nswe",
                        },
                    )
                ],
                "border": "2",
                "sticky": "nswe",
            },
        )
    ],
)

# Register both of styles and configure the background/foreground/field-background parameters.
estyle.configure(
    "EntryStyle.Filled", background="green", foreground="black", fieldbackground="green"
)
estyle.configure("EntryStyle.Empty", background="red", foreground="black", fieldbackground="red")

# Creating 2 String variables.
string_var_1 = StringVar()
string_var_2 = StringVar()

# Creating the 2 TTK entries with the default Empty style (by-default the String variable is empty)
entry_1 = ttk.Entry(root_window, style="EntryStyle.Empty", textvariable=string_var_1)
entry_2 = ttk.Entry(root_window, style="EntryStyle.Empty", textvariable=string_var_2)

entry_1.pack(padx=10, pady=10)
entry_2.pack(padx=10, pady=10)

# Entry and Variable connection. It's needed to connect the String variables with Entry widgets.
# The Style of Entry will be changed based on this structure. (I didn't fine solution to get the reference of
# Entry Widget based on StringVar object.)
entry_and_var = {str(string_var_1): entry_1, str(string_var_2): entry_2}


def callback(string_var_wid):
    """
    Callback function to change the style of Entry based on the StringVar object.
    If there is value of StringVar (There is something in the Entry field), then the style will be
    changed to "EntryStyle.Filled". In another case (The deletion is also handled)
    the style is set to "EntryStyle.Empty" (When the entry field is really empty.)
    :param string_var_wid: Reference ob StringVar object.
    :return:
    """

    if not string_var_wid.get():
        entry_and_var[str(string_var_wid)].configure(style="EntryStyle.Empty")
    else:
        entry_and_var[str(string_var_wid)].configure(style="EntryStyle.Filled")


# Set the trace for the StringVar object. If something in written (or delete) in the Entry field then these
# traces will call the callback function.
string_var_1.trace("w", lambda *_, string_variable_1=string_var_1: callback(string_var_1))
string_var_2.trace("w", lambda *_, string_variable_1=string_var_2: callback(string_var_2))

root_window.mainloop()

图形用户界面:

© www.soinside.com 2019 - 2024. All rights reserved.